<p>下面是我的最终解决方案(希望如此),它也支持使用位大小,数组类型也将分解:</p>
<pre><code>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
</code></pre>
<p>以及输出:</p>
<pre><code><Mystruct=a:0x0102 b:0x00c1 c:0x00000506 d:[0x0707,0x0808,0x0909]>
</code></pre>