不确定 Python 3.3.2 总是将结构打包到一个新的结构单元中是否正常。下面的代码演示了这个问题。
sts结构只占8位。pkt 在状态之前只有 24 位字段,因此 pkt 的大小应该是 32 位,而不是 64 位。pkt 的打印清楚地表明 Python 将 sts 打包到一个新的 32 位整数中,并留下 8 位未使用的空间以及另一个 32 位整数中的所有其他 pckt 字段
import ctypes
class sts( ctypes.BigEndianStructure ):
_fields_ = [( "valid", ctypes.c_uint8, 1 ),
( "inout", ctypes.c_uint8, 2 ),
( "exception", ctypes.c_uint8, 2 ),
( "error", ctypes.c_uint8, 3 ), ]
class pkt( ctypes.BigEndianStructure ):
_fields_ = [( "uid", ctypes.c_uint32, 8 ),
( "sid", ctypes.c_uint32, 16 ),
( "sts", sts, ), ]
print("sts {:d}-byte".format(ctypes.sizeof(sts)))
print("pkt {:d}-byte".format(ctypes.sizeof(pkt)))
a=pkt(0xFF,0xDEAD,(0x1,0x3,0x3,0x7))
print("uid {:02X}".format(a.uid))
print("sid {:02X}".format(a.sid))
print("sts {:02X}".format(ctypes.string_at(ctypes.addressof(a.sts))[0]))
for b in ctypes.string_at(ctypes.addressof(a),8):
print("{:02X}".format(b))
另一个代码来帮助解释问题。这段代码的输出表明 Python 确实以紧凑的形式打包字段,但具有结构的字段总是从一个新单元开始。
import ctypes
class sts( ctypes.BigEndianStructure ):
_fields_ = [( "valid", ctypes.c_uint8, 1 ),
( "inout", ctypes.c_uint8, 2 ),
( "exception", ctypes.c_uint8, 2 ),
( "error", ctypes.c_uint8, 3 ), ]
class pkt( ctypes.BigEndianStructure ):
_fields_ = [( "uid", ctypes.c_uint32, 8 ),
( "sid", ctypes.c_uint32, 16 ),
( "sts", sts ),
( "sts1", sts ),
( "gid", ctypes.c_uint16 ), ]
print("sts {:d}-byte".format(ctypes.sizeof(sts)))
print("pkt {:d}-byte".format(ctypes.sizeof(pkt)))
a=pkt(0xFF,0xDEAD,(0x1,0x3,0x3,0x7),(0x1,0x2,0x3,0x7),0xBEEFABCD)
print("uid {:02X}".format(a.uid))
print("sid {:02X}".format(a.sid))
print("sts {:02X}".format(ctypes.string_at(ctypes.addressof(a.sts))[0]))
for b in ctypes.string_at(ctypes.addressof(a),8):
print("{:02X}".format(b))