如何使用ctypes声明带省略号可变参数的C函数对应的Python参数类型
ctypes处理C可变参数函数的方案
ctypes的类型声明中不需要也不支持显式写...来匹配C的可变参数,不同场景的处理方式如下:
场景1:Python侧调用C的可变参数函数
这种场景你只需要在argtypes里声明前5个固定参数的类型即可,可变参数不需要显式声明:
from ctypes import CDLL, c_int, c_char_p # 加载C动态库 lib = CDLL("./你的动态库文件名.so") # C的枚举默认等价于int,const char*对应ctypes的c_char_p类型 lib.func.argtypes = [c_int, c_char_p, c_int, c_char_p, c_char_p] # 调用时直接传入可变参数即可,ctypes会自动做类型转换 lib.func(1, b"test_func", 42, b"test.c", b"age: %d, name: %s", 18, b"xiaoming")
场景2:Python实现该签名的回调函数给C调用
ctypes的CFUNCTYPE原生不支持接收C传入的可变参数(C的va_list结构没有直接的ctypes对应类型),有两种可选解决方案:
- 方案1:修改C侧代码,新增一个接收
va_list的孪生函数,例如:
Python侧实现funcv(enum_type level, const char* function, const int line, const char* file, const char* msg, va_list args)funcv的回调即可,va_list对应c_void_p类型,后续可以调用C标准库的vsprintf等函数解析参数。 - 方案2:替换ctypes为cffi库,cffi原生支持可变参数的回调声明,适配成本更低。
内容的提问来源于stack exchange,提问作者lemonhead
相关产品推荐
相关产品推荐

