长度的结构长度取决于字节顺序?

时间:2017-02-23 12:37:37

标签: python python-2.7 struct

我想使用struct.unpack()从Python 2.7中的字节字符串中获取长值,但我发现了一些奇怪的行为,我想知道这是不是一个bug,还有,我是什么可以做到这一点。

以下是:

import struct
>>> struct.unpack("L","")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 8

这是预期的行为。它需要一个8字节的字符串来提取8字节的长值。

现在我将字节顺序更改为网络字节顺序,我得到以下内容:

>>> struct.unpack("!L","")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 4

突然间,它只需要4个字节作为8字节长的值。

该怎么做,我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:1)

这里的问题是,第一种情况是struct使用计算机的本机long大小,第二种情况是使用struct的“标准” long大小。

在第一个示例中,您未指定byte-order, size, and alignment specifier@=<>!中的一个),因此struct假设'@'使用了计算机的本机值,即机器的本机long大小。为了在各个平台上保持一致,struct defines standard sizes for each type可能与您计算机的本机大小不同。除'@'以外的每个说明符都使用这些标准尺寸。

因此,在long的情况下,struct的标准是4个字节,这就是'!L'(或任何'[=<>!]L'期望有4个字节的原因。机器的本机long显然是8个字节,这就是'@L''L'期望为8的原因。如果要使用机器的本机字节顺序,但仍与{{1}兼容}的标准尺寸,我建议您使用struct指定所有格式,而不要让Python将其默认设置为'='


您可以使用'@'来检查尺寸期望值,即:

struct.calcsize

(这在我的64位Windows 10计算机上返回>>> struct.calcsize('@L'), struct.calcsize('=L') ,但在我的64位Ubuntu 16.04计算机上返回(4, 4)。)

您还可以通过编译(8, 4)脚本来检查C的值来直接检查计算机的类型大小,例如:

sizeof(long)

我跟随this guide在Windows 10计算机上编译了#include <stdio.h> int main() { printf("%li",sizeof(long)); return 0; } 脚本。