Python中如何将十六进制字节数据打包为ctypes.Structure结构体实例
十六进制数据填充ctypes结构体实现方案
from ctypes import Structure, c_uint8, sizeof class TestInfo(Structure): # 关闭字节对齐,保证结构内存布局和字段定义顺序完全一致 _pack_ = 1 _fields_ = [ ('version', c_uint8), ('lsbyte', c_uint8), ('msbyte', c_uint8), ('free_space', c_uint8 * 2), ('recent_addtime', c_uint8 * 4), ('recent_erasetime', c_uint8 * 4), ('operation_support', c_uint8) ] def uint8_arr_to_int(arr, byteorder='big'): """将ctypes的c_uint8数组转换为整数""" return int.from_bytes(bytes(arr), byteorder=byteorder) # 原始十六进制数据处理 test_data = '51 af 01 00 65 f1 52 ff 60 f4 00 c7 60 0a' # 转换为字节序列 data_bytes = bytes([int(x, 16) for x in test_data.split()]) # 校验数据长度是否和结构体大小匹配 assert len(data_bytes) == sizeof(TestInfo), "数据长度和结构体大小不匹配" # 直接填充结构体 test_info = TestInfo.from_buffer_copy(data_bytes) # 打印验证结果 print(f"TestInfo.version = 0x{test_info.version:02x}") print(f"TestInfo.lsbyte = 0x{test_info.lsbyte:02x}") print(f"TestInfo.msbyte = 0x{test_info.msbyte:02x}") print(f"TestInfo.free_space = 0x{uint8_arr_to_int(test_info.free_space):04x}") print(f"TestInfo.recent_addtime = 0x{uint8_arr_to_int(test_info.recent_addtime):08x}") print(f"TestInfo.recent_erasetime = 0x{uint8_arr_to_int(test_info.recent_erasetime):08x}") print(f"TestInfo.operation_support = 0x{test_info.operation_support:02x}")
运行输出
TestInfo.version = 0x51 TestInfo.lsbyte = 0xaf TestInfo.msbyte = 0x01 TestInfo.free_space = 0x0065 TestInfo.recent_addtime = 0xf152ff60 TestInfo.recent_erasetime = 0xf400c760 TestInfo.operation_support = 0x0a
注意事项
_pack_ = 1是必须配置的参数,否则ctypes会按照默认规则对结构体做字节对齐,导致结构内存大小大于14字节,数据填充错位- 如果业务场景中多字节数组是小端序,只需要把
uint8_arr_to_int函数的byteorder参数改为'little'即可 from_buffer_copy是ctypes结构原生提供的内存复制方法,不需要手动逐个字段赋值,代码更简洁也不容易出错
内容的提问来源于stack exchange,提问作者TheDude
相关产品推荐
相关产品推荐

