Python使用ctypes调用C++共享库函数报TypeError单字符类型错误
问题根因与修复方案
核心报错触发原因
你调用ctypes.c_char(binary)时,c_char类型仅支持传入单个字节的入参,但binary是读取的整段二进制文件内容,是长度远大于1的bytes对象,直接触发类型错误。对应C函数原型的第一个参数是const char *字符串指针,不需要用c_char转换,ctypes默认会将bytes对象自动转为const char*类型。
其他隐藏错误
NULL引用错误:Python原生没有NULL关键字,ctypes的空指针需要使用ctypes.NULL- 结构体传参错误:C函数的
void *params是指针类型,直接传结构体对象会触发值传递,需要用ctypes.byref(func_param)取结构体指针传入 - 二进制长度取值不够稳妥:读完文件后
file.tell()虽然和全文件长度一致,但直接取len(binary)作为binsz入参兼容性更好 - 参数硬编码风险:
paramssz硬编码为4不符合结构体实际大小,你的virt_buff包含两个c_int,常规平台下总大小为8字节,直接用ctypes.sizeof(virt_buff)自动计算大小更稳妥 - 缺少参数类型声明:ctypes默认的隐式类型转换容易触发隐藏内存错误,建议提前给函数声明
argtypes明确参数类型
修复后完整代码
import ctypes import pathlib class virt_buff(ctypes.Structure): _fields_ = [("x", ctypes.c_int), ("y", ctypes.c_int)] if __name__ == "__main__": libname = pathlib.Path().absolute() / "build/libfoo.so" c_lib = ctypes.CDLL(libname) # 显式声明函数参数类型,避免隐式转换错误 c_lib.foo_func.argtypes = [ ctypes.c_char_p, ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p ] func_param = virt_buff(7, 0) with open("build/fib.bin", mode='rb') as file: binary = file.read() bin_len = len(binary) c_lib.foo_func( binary, bin_len, 0x9000 + (bin_len & ~0xFFF), ctypes.byref(func_param), ctypes.sizeof(virt_buff), ctypes.NULL )
内容的提问来源于stack exchange,提问作者molecule
相关产品推荐
相关产品推荐

