Python使用ctypes封装C代码时日志文件路径参数传入异常问题
核心问题原因
你遇到的问题本质是ctypes类型定义和传参不匹配,具体有4处错误:
- C函数的第三个参数是
const char *LogFileName(字符串指针),但你在argtypes里错误定义为ctypes.POINTER(ctypes.c_char_p)(字符串指针的指针,即char **) - 传参时你把编码后的日志路径字符串又包装成了长度为1的
c_char_p数组,相当于给C函数传了char **类型的值,C代码把指针地址当成了文件名解析,所以生成乱码文件名 - 函数返回值定义错误:
restypes是复数写法,且不需要用列表包装,单个int返回值直接赋值restype即可 - logfile的debug提示逻辑错误:你识别到
logfile参数后直接设self.log_flag = True,没有放到ignored_args里,后续if "logfile" in ignored_args:的判断永远不会触发,不会打印激活提示
修复步骤
- 修正C函数的类型定义
- 简化日志路径的编码传参逻辑,直接传编码后的bytes即可
- 修正logfile的debug提示逻辑
- 修正返回值定义
修改后的核心代码片段
1. __init__方法内的函数签名定义部分
# Settings C library's signature datatype self.LIBC.lisaf_phasemeter_main.argtypes= [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p), ctypes.c_char_p,] # 注意restype是单数,不用列表 self.LIBC.lisaf_phasemeter_main.restype = ctypes.c_int
2. start方法内的日志路径编码和传参部分
# 删掉原来包装成c_char_p数组的代码,直接编码即可 if self.log_flag : self.encoded_path_to_log_file = self.path_to_log_file.encode('utf-8') # 调用C函数部分保持不变,ctypes会自动把c_char_p类型的bytes传给对应参数 if self.log_flag : self.status = self.LIBC.lisaf_phasemeter_main(len(self.encoded_options), self.encoded_options,self.encoded_path_to_log_file) else : self.status = self.LIBC.lisaf_phasemeter_main(len(self.encoded_options), self.encoded_options,None)
3. 修正logfile的debug提示逻辑
把原来的:
if ignored_args: print("Ignored given options : ",*ignored_args) if "logfile" in ignored_args: print("Logfile option activated")
改成:
if ignored_args: print("Ignored given options : ",*ignored_args) if self.log_flag: print("Logfile option activated")
内容的提问来源于stack exchange,提问作者Hugo Castaing
相关产品推荐
相关产品推荐

