Python调用C++类函数出现段错误,求正确调用方案
解决Python通过ctypes调用C++类函数的段错误问题
你的代码出现段错误的核心原因是:ctypes默认会将C函数的返回值当作int类型处理,但DemoCpp返回的是DemoClass*指针。在64位系统中,指针占8字节,int仅占4字节,这会导致指针被截断,后续调用DemoCppFunction时传入的是错误的内存地址,最终触发段错误。
修正方案
只需在Python脚本中为C函数指定正确的参数类型和返回值类型即可,C++代码无需修改。
修正后的Python脚本
from ctypes import cdll, c_int, c_void_p lib = cdll.LoadLibrary('./test.so') # 为DemoCpp指定参数类型和返回值类型 lib.DemoCpp.argtypes = [c_int, c_int] lib.DemoCpp.restype = c_void_p # 用void*表示C++类指针,避免被当作int截断 # 为DemoCppFunction指定参数类型 lib.DemoCppFunction.argtypes = [c_void_p] lib.DemoCppFunction.restype = None class CppClass(): def __init__(self, v1: int, v2: int): self.obj = lib.DemoCpp(v1, v2) def demoFunction(self): lib.DemoCppFunction(self.obj) f = CppClass(2, 3) f.demoFunction()
代码说明
argtypes:指定C函数的参数类型,确保Python传递的参数能正确转换为C语言类型,避免类型不匹配问题。restype:指定C函数的返回值类型,这里用c_void_p表示通用指针,保证64位系统下指针地址不会被截断。
运行结果
修正后执行Python脚本,会正常输出:
Hello C++! output: a = 2, b = 3
额外优化:避免内存泄漏
如果需要长期使用C对象,建议在C代码中添加销毁函数,避免内存泄漏:
在C的extern "C"块中新增:
void DemoCppDestroy(DemoClass* demo){ delete demo; }
然后在Python脚本中补充:
# 指定销毁函数的参数类型 lib.DemoCppDestroy.argtypes = [c_void_p] lib.DemoCppDestroy.restype = None # 在CppClass的析构函数中调用销毁函数 class CppClass(): def __init__(self, v1: int, v2: int): self.obj = lib.DemoCpp(v1, v2) def demoFunction(self): lib.DemoCppFunction(self.obj) def __del__(self): lib.DemoCppDestroy(self.obj)
内容的提问来源于stack exchange,提问作者Cino
相关产品推荐
相关产品推荐

