如何获取用于格式化十六进制输出的python ctypes结构成员的长度?

如何获取用于格式化十六进制输出的python ctypes结构成员的长度?,python,ctypes,Python,Ctypes,使用此代码: 从ctypes导入* 类Tracerec(bigendian结构): 定义报告(自我): textlist=list() 对于名称,*d在self.\u字段中键入: value=getattr(self,name) 如果类型(值)==int:textlist.append(f'{name}:0x{value:x}') else:textlist.append(f'{name}:{value}') 全文=''.join(文本列表) 返回f“” 定义获取项目(自我,i): 如果类型(i

使用此代码:

从ctypes导入*
类Tracerec(bigendian结构):
定义报告(自我):
textlist=list()
对于名称,*d在self.\u字段中键入:
value=getattr(self,name)
如果类型(值)==int:textlist.append(f'{name}:0x{value:x}')
else:textlist.append(f'{name}:{value}')
全文=''.join(文本列表)
返回f“”
定义获取项目(自我,i):
如果类型(i)==str:return getattr(self,i)
返回getattr(self,self.\u字段[i][0])
定义(自我):
返回len(自身字段)
类Mystruct(Tracerec):
_字段=[
('a',c_uint16),
('b',c_uint16),
('c',c_uint32),
]
缓冲区=b'\x01\x02\x03\x04\x00\x00\x05\x06'
x=Mystruct.from\u buffer\u copy(buffer)
x
我得到这个输出:

<Mystruct=a:0x102 b:0x304 c:0x506>
请尝试
sizeof(*dtype)
并向左填充0:

...
for name, *dtype in self._fields_:
    value = getattr(self, name)
    size = sizeof(*dtype) * 2
    if type(value) == int: textlist.append(f'{name}:0x{value:0{size}x}')
    ...

下面是我的最终解决方案(希望如此),它也支持使用位大小,数组类型也将分解:

class Tracerec(BigEndianStructure):
    # do not define _fields_ in this parent class
    
    def _format_value(self, value, dtype):
        if isinstance(value, Array):
            # Use Array undocumented _type_:
            text = ','.join([ self._format_value(x, value._type_) for x in value ])
            return f'[{text}]'
        elif type(value) == int:
            size = sizeof(dtype) * 2   # size mutliply by byte width
            return f'0x{value:0{size}x}'
        else:
            return f'{value}'
    
    def _format_field(self, field):
        name, dtype, *bitsize = field
        value = getattr(self, name)
        return f'{name}:{self._format_value(value, dtype)}'

    def __repr__(self):
        text = ' '.join( [ self._format_field(x) for x in self._fields_ ] )
        return f'<{self.__class__.__name__}={text}>'
    def __getitem__(self, i):
        if type(i)==str: return getattr(self, i)
        return getattr(self, self._fields_[i][0])
    def __len__(self):
        return len(self._fields_)

class Mystruct(Tracerec):
    _fields_ = [
        ('a', c_uint16),
        ('b', c_uint16,14),
        ('c', c_uint32),
        ('d', c_uint16 * 3)
    ]

buffer = b'\x01\x02\x03\x04\x00\x00\x05\x06\x07\x07\x08\x08\x09\x09\0x0\0x0'
x = Mystruct.from_buffer_copy(buffer)
x
class Tracerec(bigendian结构):
#不要在此父类中定义_字段
定义格式值(自身、值、数据类型):
如果isinstance(值、数组):
#使用未记录的数组类型:
text=',join([self.\u format\u value(x,value.\u type\u)表示值中的x])
返回f'[{text}]'
elif类型(值)==int:
size=sizeof(dtype)*2#按字节宽度可变大小
返回f'0x{值:0{size}x}'
其他:
返回f'{value}'
定义格式字段(自身,字段):
名称,数据类型,*位大小=字段
value=getattr(self,name)
返回f'{name}:{self.\u format\u value(value,dtype)}'
定义报告(自我):
text=''.join([self.\u格式\u字段(x)表示self.\u字段中的x])
返回f“”
定义获取项目(自我,i):
如果类型(i)==str:return getattr(self,i)
返回getattr(self,self.\u字段[i][0])
定义(自我):
返回len(自身字段)
类Mystruct(Tracerec):
_字段=[
('a',c_uint16),
('b',c_uint16,14),
('c',c_uint32),
('d',c_uint16*3)
]
缓冲区=b'\x01\x02\x03\x04\x00\x00\x05\x06\x07\x07\x08\x08\x09\x09\0x0\0x0'
x=Mystruct.from\u buffer\u copy(buffer)
x
以及输出:

<Mystruct=a:0x0102 b:0x00c1 c:0x00000506 d:[0x0707,0x0808,0x0909]>

您好,很有意思,不确定这是否有意思
<Mystruct=a:0x0102 b:0x00c1 c:0x00000506 d:[0x0707,0x0808,0x0909]>