如何通过ctypes从Python调用C++代码时按引用返回同一对象?
问题原因
- 你的C函数返回原对象的引用,但Python的ctypes将
restype设置为PEParserBase时,会把C返回的结构体数据拷贝到新的Python结构体实例中,因此返回的是全新对象,ID自然和原实例不同。 - ctypes无法直接映射C++的引用类型到Python的对象引用,默认采用值拷贝逻辑处理结构体返回值。
修复方案
方案一:直接复用原实例(推荐)
C++函数已通过传入的指针修改了原PEParserBase的内容,Python中的原实例pEParserBase已同步更新,无需返回新实例。调整包装函数如下:
def testWrapper(peParserBase, _instanceDLL): _instanceDLL.test.argtypes = [ctypes.POINTER(PEParserBase)] _instanceDLL.test.restype = None # 忽略返回值,因原实例已被修改 _instanceDLL.test(ctypes.byref(peParserBase)) return peParserBase # 返回原实例
调用后,testWrapper返回的就是原实例,ID与pEParserBase一致,且pEParserBase.bytes会被修改为12345。
方案二:通过指针获取原实例
若需通过C++返回值获取原实例,可将restype设为指针类型,再通过contents获取原实例:
def testWrapper(peParserBase, _instanceDLL): _instanceDLL.test.argtypes = [ctypes.POINTER(PEParserBase)] _instanceDLL.test.restype = ctypes.POINTER(PEParserBase) # 通过返回的指针获取原实例 return _instanceDLL.test(ctypes.byref(peParserBase)).contents
此方式返回的对象与pEParserBase为同一实例,ID完全一致。
内容的提问来源于stack exchange,提问作者Paul Gigel
相关产品推荐
相关产品推荐

