我在使用ctypes从应该返回字符串的C ++库(用extern C包装)中调用函数时遇到问题。我很确定我已经为ctypes接口正确设置了我的argtypes和restype,该函数应该返回一个字符串,但是无论我返回的结果如何,都是空字符串。
C ++代码:
const char* disasmC_PEProgram_getSections(PEProgram *p) {
return p->getSections().c_str();
}
Python代码:
lib.disasmC_PEProgram_getSections.argtypes = [ctypes.c_void_p]
lib.disasmC_PEProgram_getSections.restype = ctypes.c_char_p
resultStr = lib.disasmC_PEProgram_getSections(self.peProgram_p)
# Displays empty string for resultStr!
print "Result: %s" % (resultStr,)
答案 0 :(得分:1)
我的猜测是从disasmC_PEProgram_getSections()
返回的值是局部变量,或者包含空值或其他内容。如果您需要更具体的帮助,请提供MCVE。
这是我的MCVE,显示您的Python代码正确。请注意,我的C ++代码返回对对象中字符串的引用,以确保字符串的生存期一直持续到对象被销毁为止。
test.cpp
#include <string>
using namespace std;
#define API __declspec(dllexport) // Windows-specific export
class PEProgram
{
string section;
public:
PEProgram() : section("section") {}
const string& getSections() const { return section; }
};
extern "C" {
API PEProgram* PEProgram_new() { return new PEProgram(); }
API void PEProgram_delete(PEProgram* p) { delete p; }
API const char* disasmC_PEProgram_getSections(PEProgram *p) {
return p->getSections().c_str();
}
}
test.py
#!python36
import ctypes
lib = ctypes.CDLL('test')
lib.PEProgram_new.argtypes = None
lib.PEProgram_new.restype = ctypes.c_void_p
lib.PEProgram_delete.argtypes = [ctypes.c_void_p]
lib.PEProgram_delete.restype = None
p = lib.PEProgram_new()
lib.disasmC_PEProgram_getSections.argtypes = [ctypes.c_void_p]
lib.disasmC_PEProgram_getSections.restype = ctypes.c_char_p
resultStr = lib.disasmC_PEProgram_getSections(p)
# Displays empty string for resultStr!
print(f'Result: {resultStr}')
lib.PEProgram_delete(p)
输出
Result: b'section'
请注意,如果我的课程是:
class PEProgram
{
public:
string getSections() const { return "section"; }
};
然后我得到b''
作为Python中的值。这是因为disasmC_PEProgram_getSections
返回的字符串现在是一个临时值,在函数disasmC_PEProgram_getSections
返回之后将被销毁。现在返回的const char*
指向已释放的内存,并且发生未定义的行为。