Python 中 ctypes 的 C_ulong_Array_40 转换为列表或字符串的方法
核心问题定位
你遇到的报错本质是write_tofile内部实现会对传入的data执行字符串拼接操作,而c_ulong_Array_40是ctypes映射的C语言原生定长无符号长整型数组类型,本身不支持和Python字符串执行加法运算,属于类型不兼容问题,和ReadSub函数的调用逻辑无关。
可行转换方案
方案1:转换为Python原生整数列表
ctypes生成的C数组本身支持直接迭代,转列表的逻辑非常简单:
err, length, data = card.ReadSub(2) # 直接遍历C数组,得到由Python int组成的原生列表 data_py_list = list(data) write_tofile(1, data_py_list)
转换后的列表固定包含40个元素,每个元素自动对应C数组里的c_ulong值,不需要额外做类型解析。
如果需要过滤数组里的无效初始化数据,可以结合返回的有效长度参数做截断:
err, length, data = card.ReadSub(2) # 仅取实际返回的有效长度范围内的数据 valid_data = list(data)[:length] write_tofile(1, valid_data)
方案2:转换为可写入的长字符串
根据你的使用场景,可以选择两种拼接逻辑:
- 把每个数值转成十进制文本直接拼接成长字符串:
err, length, data = card.ReadSub(2) data_str = ''.join(str(item) for item in data) write_tofile(1, data_str) - 提取C数组对应的原始二进制字节流(硬件调试场景下推荐使用,完全保留原始内存值):
这种方式得到的bytes对象是Python原生类型,和字符串拼接、文件写入操作的兼容性远高于C数组类型,基本不会触发类型不匹配的报错。import ctypes err, length, data = card.ReadSub(2) # 基于数组的内存地址、总大小提取原始bytes对象 data_bytes = ctypes.string_at( ctypes.addressof(data), ctypes.sizeof(data) ) write_tofile(1, data_bytes)
常见踩坑提醒
- 不要直接对
c_ulong_Array_40类型对象执行str()转换,这种操作只会返回类似<c_ulong_Array_40 object at 0x7fxxx>的内存地址描述,完全拿不到数组内的实际数值。 - 转bytes的时候不需要手动遍历每个ulong值做打包,直接用ctypes的内存提取方法效率更高,也不会出现字节序转换的偏差。
内容的提问来源于stack exchange,提问作者Martin.E
相关产品推荐
相关产品推荐

