结构包 return 太长

struct pack return is too long

我正在尝试使用 struct.pack 函数

import struct
values = (0, 44)
s = struct.Struct('HI')
b = s.pack(*values)
print(b)
print(str(len(b)))

它给了我这个输出:

b'\x00\x00\x00\x00,\x00\x00\x00'
8

python docs 说:

Format - C Type         - Python type - Standard size - Notes

H      - unsigned short - integer     - 2             - (3)

I      - unsigned int   - integer     - 4             - (3)

所以 len() 应该是 2 + 4 = 6,我需要大小为 6

的字节

有什么想法吗?

我在 Windows 10

上使用 Python 3.6

大小计算不会直接添加到包含的本机类型。您应该使用 struct.calcsize:

计算大小
In [8]: struct.calcsize('HI')
Out[8]: 8

pack 将添加填充字节,以便第二个整数是 4 字节对齐的。来自 the documentation:

By default, the result of packing a given C struct includes pad bytes in order to maintain proper alignment for the C types involved; To ... omit implicit pad bytes, use standard size and alignment instead of native size and alignment: see Byte Order, Size, and Alignment for details

这是 "Data structure padding" 的结果。它将填充 H(2 个字节 + 2 个字节填充),使其与 I(4 个字节)对齐。

不过,如果您需要减小尺寸,可以尝试调整顺序。引用维基百科:

It is possible to change the alignment of structures to reduce the memory they require (or to conform to an existing format) by reordering structure members or changing the compiler’s alignment (or “packing”) of structure members.

例如,在我的电脑上,只要交换 HI:

就可以了
import struct
values = (0, 1)
s = struct.Struct('IH')         # swapped H and I
b = s.pack(*values)
print(b)                        # b'\x00\x00\x00\x00\x01\x00'
print(str(len(b)))              # 6
print(struct.calcsize('IH'))    # 6
print(struct.calcsize('HI'))    # 8