如何在Python中通过ctypes调用带char**参数的C++ DLL函数?
解决Python调用C++ DLL中char**参数的段错误问题
问题分析
当前代码触发段错误的核心原因:仅声明了ctypes.POINTER(ctypes.POINTER(c_char))类型,未创建实际可写入的内存实例,直接传入类型而非实例会导致非法内存访问。
正确调用方法
根据C++示例的逻辑(手动分配内存后传入指针地址),在Python中可通过ctypes.create_string_buffer分配缓冲区,再通过ctypes.pointer获取缓冲区指针的地址(即char**类型)传入函数。
完整代码示例
import ctypes # 加载动态链接库 libc = ctypes.CDLL("AxECR.so") # 定义函数的返回类型和参数类型 libc.create_object.restype = ctypes.c_void_p # CAxClass* 用c_void_p表示 libc.get_DLLVersion.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))] libc.get_DLLVersion.restype = None # 创建CAxClass实例 ecr = libc.create_object() # 分配足够大的缓冲区(对应C++中的malloc(50)) buffer_size = 50 version_buffer = ctypes.create_string_buffer(buffer_size) # 调用函数:传入实例指针和缓冲区指针的地址(即char**) libc.get_DLLVersion(ecr, ctypes.pointer(version_buffer)) # 读取并打印结果(转成Python字符串) print(f"strdll = {version_buffer.value.decode('utf-8')}")
关键说明
create_string_buffer(buffer_size):创建指定大小的可写字节缓冲区,对应C++中malloc分配的内存块,其地址为char*类型。ctypes.pointer(version_buffer):获取缓冲区指针的地址,即char**类型,匹配函数的第二个参数要求。- 若DLL内部会自行分配内存(而非使用传入的缓冲区),则需调整为以下写法,调用后记得使用DLL提供的内存释放函数(若有)避免泄漏:
# 适用于DLL内部分配内存的场景 version_ptr = ctypes.POINTER(ctypes.c_char)() libc.get_DLLVersion(ecr, ctypes.byref(version_ptr)) print(f"strdll = {version_ptr.value.decode('utf-8')}") # 若DLL提供释放函数,比如free_version,需调用: # libc.free_version(version_ptr)
内容的提问来源于stack exchange,提问作者BRAiNPet
相关产品推荐
相关产品推荐

