Python使用ctypes调用FEUSB_GetScanListPara参数声明错误求助
两次报错原因解析
第一版代码报错原因
- 第二个参数类型不匹配:C函数的第二个参数是
const char*类型的字符串常量,但你在argtypes中将其声明为ctypes.c_wchar_p(宽字符指针),且传入的是Python原生字符串,实际传递给C函数的是宽字符格式的参数,函数无法识别"Device-ID"的参数名,返回参数未知错误。 - 第三个参数类型声明错误:C端的
char sDeviceSerialNumber[32]传参时会退化为char*,但你在argtypes中将其声明为ctypes.POINTER(ctypes.c_char_p)(二级字符指针),参数类型完全不匹配。 - 传参逻辑冗余:你额外将缓冲区地址封装为
c_char_p后又用byref取址,实际传入的是二级指针,和C函数要求的参数类型不符。
编辑1版本报错原因
这一版的argtypes声明已经正确,但传参逻辑错误:ctypes.create_string_buffer()返回的缓冲区实例本身就可以直接作为c_char_p类型的参数传递,你额外加了ctypes.byref()取址,相当于传入了char**类型的参数,和argtypes中声明的c_char_p不匹配,直接触发类型错误。
ctypes调用C数组类出参的正确规则
- 参数声明规则:C端的定长字符数组作为出参时,形参会自动退化为
char*,所以argtypes对应位置直接声明为ctypes.c_char_p即可,不需要声明为二级指针或者数组类型。 - 出参构造规则:直接用
ctypes.create_string_buffer(数组长度)构造缓冲区即可,不需要额外封装指针或者取地址操作,构造出来的缓冲区实例可以直接作为参数传递给C函数。 - 入参匹配规则:如果C端的字符串入参是
const char*类型,Python端需要传入bytes类型的参数,不能直接传入str类型的原生字符串。 - 结果取值规则:C函数执行完成后,直接取
缓冲区实例.value即可得到bytes类型的出参结果,需要字符串的话调用对应的decode方法转码即可。
内容的提问来源于stack exchange,提问作者user15950833
相关产品推荐
相关产品推荐

