ctypes-函数仅返回空字符串

时间:2018-06-22 13:48:34

标签: python ctypes

我在使用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,) 

1 个答案:

答案 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*指向已释放的内存,并且发生未定义的行为。