[英]Struct length of long depending on byte order?
I want to use struct.unpack()
to get a long value from a byte string in Python 2.7, but I found some strange behaviour and I would like to know if this is a bug or not, and also, what I can do to get around it.我想使用
struct.unpack()
从 Python 2.7 中的字节字符串中获取长值,但我发现了一些奇怪的行为,我想知道这是否是一个错误,以及我能做些什么绕过它。
What happens is the following:发生的情况如下:
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
This is the expected behaviour.这是预期的行为。 It wants an 8-byte string to extract the 8-byte long value.
它需要一个 8 字节的字符串来提取 8 字节长的值。
Now I change the byte order to network byte order and I get the following:现在我将字节顺序更改为网络字节顺序,我得到以下信息:
>>> struct.unpack("!L","")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 4
Suddenly it only wants 4 bytes for the 8-byte long value.突然间它只需要 4 个字节作为 8 字节长的值。
What is up with that, and what can I do to get around this?这是怎么回事,我能做些什么来解决这个问题?
The issue here is that struct
is using your machine's native long
size in the first case, and struct
's "standard" long
size in the second.这里的问题是
struct
正在使用您的计算机的本地long
在第一种情况下大小和struct
的‘标准’ long
尺寸在第二位。
In the first example, you don't specify a byte-order, size, and alignment specifier (one of @=<>!
) so struct
assumes '@'
, which uses your machine's native values, namely your machine's native long
size.在第一个示例中,您没有指定字节顺序、大小和对齐说明符(
@=<>!
),因此struct
假定'@'
,它使用您机器的本机值,即您机器的本long
尺寸。 In order to be consistent across platforms,struct
defines standard sizes for each type , which may differ from your machine's native sizes.为了跨平台保持一致,
struct
为每个 type 定义了标准大小,这可能与您机器的本机大小不同。 Every specifier except for '@'
uses these standard sizes.除了
'@'
之外的每个说明符都使用这些标准大小。
So, in the case of long
, struct
's standard is 4 bytes, which is why '!L'
(or any '[=<>!]L'
expects 4 bytes. However, your machine's native long
is apparently 8 bytes, which is why '@L'
or 'L'
expects 8. If you want to use your machine's native byte-order, but still be compatible with struct
's standard sizes, I would recommend that you specify all formats with '='
, instead of letting Python default it to '@'
.因此,在
long
的情况下, struct
的标准是 4 个字节,这就是为什么'!L'
(或任何'[=<>!]L'
需要 4 个字节。但是,您机器的本机long
显然是 8 个字节,这就是为什么'@L'
或'L'
需要 8。如果您想使用机器的本机字节顺序,但仍然与struct
的标准大小兼容,我建议您使用'='
指定所有格式,而不是让 Python 默认为'@'
。
You can check the size expectation with struct.calcsize
, ie:您可以使用
struct.calcsize
检查大小期望,即:
>>> struct.calcsize('@L'), struct.calcsize('=L')
(this returns (4, 4)
on my 64-bit Windows 10 machine, but (8, 4)
on my 64-bit Ubuntu 16.04 machine.) (这在我的 64 位 Windows 10 机器上返回
(4, 4)
,但在我的 64 位 Ubuntu 16.04 机器上返回(8, 4)
。)
You can also directly check your machine's type size by compiling a C
script to check the value of sizeof(long)
, for example:您还可以通过编译
C
脚本来检查sizeof(long)
的值,直接检查您机器的类型大小,例如:
#include <stdio.h>
int main()
{
printf("%li",sizeof(long));
return 0;
}
I followed this guide to compile the C
script on my Windows 10 machine.我按照本指南在我的 Windows 10 机器上编译
C
脚本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.