# 定义一个包含数组的结构体数组的长度在创建实例时确定 class DynamicArrayStruct(ctypes.Structure): _pack_ 1 _fields_ [(pro_fix_head, c_ushort), (src_mac, c_ubyte * 0), (dsr_mac, c_ubyte * 0), (module_id, c_ushort), (cli_crc, c_ushort), (msg_id, c_uint), (msg_lenx, c_uint) ] print(sizeof(DynamicArrayStruct)) def create_dynamic_array_struct(array_length): # 创建一个适当长度的数组类型 ArrayType array_length # 动态地添加数组字段到结构体定义中 class DynamicArrayStructWithLength(DynamicArrayStruct): _pack_ 1 _fields_ [(pro_fix_head, c_ushort), (src_mac, c_ubyte * ArrayType), (dsr_mac, c_ubyte * ArrayType), (module_id, c_ushort), (cli_crc, c_ushort), (msg_id, c_uint), (msg_len, c_uint) ] # 创建结构体实例 instance DynamicArrayStructWithLength() print(sizeof(instance)) return instanceimport ctypes import ctypesprint import time from datetime import datetime from sealinxcmdenum import * import binascii class sealinxcmdmalloc(): num 1 def __init__(self,len): self._n len self.cmd self.cmd_malloc() self.check check_t() self.cmd.type (0,0,0,0,0) self.cmd.type.length self.getlen() ############################################################### sealinxcmdmalloc.num 1 self.cmd.internaldata.number int(sealinxcmdmalloc.num) self.cmd.internaldata.sendtimestamp int(time.time()) self.cmd.internaldata.txrx ctypes.c_int(0xffffffff) self.cmd.internaldata.ack int(0) self.cmd.internaldata.ifrandom ctypes.c_char(0x00) # 将Unix时间戳转换为datetime对象 dt_object datetime.fromtimestamp( self.cmd.internaldata.sendtimestamp) print(dt_object) def cmd_malloc(self): n self._n ############################################################### class _databusiness_pkt_data_t(ctypes.Structure): _pack_ 1 _fields_ [ (number, ctypes.c_char), (sendtimestamp, ctypes.c_int), (txrx, ctypes.c_int), (ack, ctypes.c_char), (ifrandom, ctypes.c_char), (data, ctypes.c_char*n) ] class _databusiness_t(ctypes.Structure): #//数据 _pack_ 1 _fields_ [(type, basetype_t), (internaldata, _databusiness_pkt_data_t) ] return _databusiness_t() def getlen(self): return ctypes.sizeof(self.cmd_malloc()) def cmdinit(self): pass def cmdtostr(self): # 将结构体打包成字节流 packed_data ctypes.string_at(ctypes.addressof(self.cmd), ctypes.sizeof(self.cmd)) # 打印字节流 #print(packed_data) hex_string binascii.hexlify(packed_data).decode(utf-8) #print(hex_string) # 输出: 01 return hex_string def checktostr(self): # 将结构体打包成字节流 packed_data ctypes.string_at(ctypes.addressof(self.check ), ctypes.sizeof(self.check )) # 打印字节流 #print(packed_data) hex_string binascii.hexlify(packed_data).decode(utf-8) #print(hex_string) # 输出: 01 return hex_string def checkparitytostr(self): # 检查 self.check.parity 的类型 if isinstance(self.check.parity, bytes): # 如果是 bytes 类型直接处理 packed_data self.check.parity elif isinstance(self.check.parity, ctypes.c_char): # 如果是 ctypes.c_char 类型使用 ctypes.addressof packed_data ctypes.string_at(ctypes.addressof(self.check.parity), ctypes.sizeof(self.check.parity)) else: raise TypeError(self.check.parity must be a bytes or ctypes.c_char instance) # 将字节流转换为十六进制字符串 hex_string binascii.hexlify(packed_data).decode(utf-8) return hex_string def cmdprint(self): ctypesprint.print_members(self.cmd) def checkprint(self): ctypesprint.print_members(self.check) def getcmdbuf(self): return self.cmdtostr() self.checktostr() # def internaldatatostr(self): # 将结构体打包成字节流 packed_data ctypes.string_at(ctypes.addressof(self.cmd.internaldata), ctypes.sizeof(self.cmd.internaldata )) # 打印字节流 #print(packed_data) hex_string binascii.hexlify(packed_data).decode(utf-8) #print(hex_string) # 输出: 01 return hex_string def bytescopytostruct(self,data_bytes:bytes): # 确保bytes对象的长度与结构体大小匹配 struct_size ctypes.sizeof(self.cmd.internaldata) assert len(data_bytes) struct_size, Bytes object length does not match structure size # 将bytes对象转换为buffer信息 buf (ctypes.c_char * len(data_bytes)).from_buffer_copy(data_bytes) # 创建结构体实例并从buffer中加载数据 temclaasstype(self.cmd.internaldata).__name__ if(temclaassinstructbusiness_pkt_data_t): self.cmd.internaldata instructbusiness_pkt_data_t.from_buffer_copy(buf) if(temclaassdatabusiness_pkt_data_t): self.cmd.internaldata databusiness_pkt_data_t.from_buffer_copy(buf) if(temclaassfeebackbusiness_pkt_data_t): self.cmd.internaldata feebackbusiness_pkt_data_t.from_buffer_copy(buf) if __name__ __main__: test sealinxcmdmalloc() cmd test.cmdtostr() check test.checktostr() print (test.getcmdbuf())
python 动态长度结构体
发布时间:2026/5/15 23:07:28
# 定义一个包含数组的结构体数组的长度在创建实例时确定 class DynamicArrayStruct(ctypes.Structure): _pack_ 1 _fields_ [(pro_fix_head, c_ushort), (src_mac, c_ubyte * 0), (dsr_mac, c_ubyte * 0), (module_id, c_ushort), (cli_crc, c_ushort), (msg_id, c_uint), (msg_lenx, c_uint) ] print(sizeof(DynamicArrayStruct)) def create_dynamic_array_struct(array_length): # 创建一个适当长度的数组类型 ArrayType array_length # 动态地添加数组字段到结构体定义中 class DynamicArrayStructWithLength(DynamicArrayStruct): _pack_ 1 _fields_ [(pro_fix_head, c_ushort), (src_mac, c_ubyte * ArrayType), (dsr_mac, c_ubyte * ArrayType), (module_id, c_ushort), (cli_crc, c_ushort), (msg_id, c_uint), (msg_len, c_uint) ] # 创建结构体实例 instance DynamicArrayStructWithLength() print(sizeof(instance)) return instanceimport ctypes import ctypesprint import time from datetime import datetime from sealinxcmdenum import * import binascii class sealinxcmdmalloc(): num 1 def __init__(self,len): self._n len self.cmd self.cmd_malloc() self.check check_t() self.cmd.type (0,0,0,0,0) self.cmd.type.length self.getlen() ############################################################### sealinxcmdmalloc.num 1 self.cmd.internaldata.number int(sealinxcmdmalloc.num) self.cmd.internaldata.sendtimestamp int(time.time()) self.cmd.internaldata.txrx ctypes.c_int(0xffffffff) self.cmd.internaldata.ack int(0) self.cmd.internaldata.ifrandom ctypes.c_char(0x00) # 将Unix时间戳转换为datetime对象 dt_object datetime.fromtimestamp( self.cmd.internaldata.sendtimestamp) print(dt_object) def cmd_malloc(self): n self._n ############################################################### class _databusiness_pkt_data_t(ctypes.Structure): _pack_ 1 _fields_ [ (number, ctypes.c_char), (sendtimestamp, ctypes.c_int), (txrx, ctypes.c_int), (ack, ctypes.c_char), (ifrandom, ctypes.c_char), (data, ctypes.c_char*n) ] class _databusiness_t(ctypes.Structure): #//数据 _pack_ 1 _fields_ [(type, basetype_t), (internaldata, _databusiness_pkt_data_t) ] return _databusiness_t() def getlen(self): return ctypes.sizeof(self.cmd_malloc()) def cmdinit(self): pass def cmdtostr(self): # 将结构体打包成字节流 packed_data ctypes.string_at(ctypes.addressof(self.cmd), ctypes.sizeof(self.cmd)) # 打印字节流 #print(packed_data) hex_string binascii.hexlify(packed_data).decode(utf-8) #print(hex_string) # 输出: 01 return hex_string def checktostr(self): # 将结构体打包成字节流 packed_data ctypes.string_at(ctypes.addressof(self.check ), ctypes.sizeof(self.check )) # 打印字节流 #print(packed_data) hex_string binascii.hexlify(packed_data).decode(utf-8) #print(hex_string) # 输出: 01 return hex_string def checkparitytostr(self): # 检查 self.check.parity 的类型 if isinstance(self.check.parity, bytes): # 如果是 bytes 类型直接处理 packed_data self.check.parity elif isinstance(self.check.parity, ctypes.c_char): # 如果是 ctypes.c_char 类型使用 ctypes.addressof packed_data ctypes.string_at(ctypes.addressof(self.check.parity), ctypes.sizeof(self.check.parity)) else: raise TypeError(self.check.parity must be a bytes or ctypes.c_char instance) # 将字节流转换为十六进制字符串 hex_string binascii.hexlify(packed_data).decode(utf-8) return hex_string def cmdprint(self): ctypesprint.print_members(self.cmd) def checkprint(self): ctypesprint.print_members(self.check) def getcmdbuf(self): return self.cmdtostr() self.checktostr() # def internaldatatostr(self): # 将结构体打包成字节流 packed_data ctypes.string_at(ctypes.addressof(self.cmd.internaldata), ctypes.sizeof(self.cmd.internaldata )) # 打印字节流 #print(packed_data) hex_string binascii.hexlify(packed_data).decode(utf-8) #print(hex_string) # 输出: 01 return hex_string def bytescopytostruct(self,data_bytes:bytes): # 确保bytes对象的长度与结构体大小匹配 struct_size ctypes.sizeof(self.cmd.internaldata) assert len(data_bytes) struct_size, Bytes object length does not match structure size # 将bytes对象转换为buffer信息 buf (ctypes.c_char * len(data_bytes)).from_buffer_copy(data_bytes) # 创建结构体实例并从buffer中加载数据 temclaasstype(self.cmd.internaldata).__name__ if(temclaassinstructbusiness_pkt_data_t): self.cmd.internaldata instructbusiness_pkt_data_t.from_buffer_copy(buf) if(temclaassdatabusiness_pkt_data_t): self.cmd.internaldata databusiness_pkt_data_t.from_buffer_copy(buf) if(temclaassfeebackbusiness_pkt_data_t): self.cmd.internaldata feebackbusiness_pkt_data_t.from_buffer_copy(buf) if __name__ __main__: test sealinxcmdmalloc() cmd test.cmdtostr() check test.checktostr() print (test.getcmdbuf())