gpt4 book ai didi

Python struct calsize 与实际不同

转载 作者:太空狗 更新时间:2023-10-30 01:25:53 26 4
gpt4 key购买 nike

我正在尝试使用 python struct 从二进制文件中读取一个短的和一个长的。

但是

print(struct.calcsize("hl")) # o/p 16

这是错误的,它应该是短的 2 个字节和长的 8 个字节。我不确定我是否以错误的方式使用了 struct 模块。

当我打印每个值时,它是

print(struct.calcsize("h")) # o/p 2
print(struct.calcsize("l")) # o/p 8

有没有办法强制 python 保持数据类型的精度?

最佳答案

默认结构对齐规则,16 是正确答案。每个字段都对齐以匹配其大小,因此您最终得到两个字节的 short,然后是六个字节的填充(以到达与八字节的倍数对齐的下一个地址),然后是八个字节对于 long

您可以使用 byte order prefix (它们中的任何一个禁用填充),但它们禁用机器 native 大小(因此 struct.calcsize("=l") 在所有系统上将是固定的 4 个字节,和 struct.calcsize("=hl") 在所有系统上都是 6 字节,而不是 10,即使在具有 8 字节 long 的系统上也是如此。

如果您想使用具有非默认填充规则的机器 native 类型计算任意结构的结构大小,您需要转到 ctypes 模块,定义您的 ctypes.Structure使用所需的 _pack_ 设置子类,然后使用 ctypes.sizeof检查大小,例如:

from ctypes import Structure, c_long, c_short, sizeof

class HL(Structure):
_pack_ = 1 # Disables padding for field alignment
# Defines (unnamed) fields, a short followed by long
_fields_ = [("", c_short),
("", c_long)]

print(sizeof(HL))

根据需要输出 10

如果需要,这可以分解为实用函数(这是一个简化的示例,不处理所有 struct 格式代码,但您可以根据需要扩展):

from ctypes import *

FMT_TO_TYPE = dict(zip("cb?hHiIlLqQnNfd",
(c_char, c_byte, c_bool, c_short, c_ushort, c_int, c_uint,
c_long, c_ulong, c_longlong, c_ulonglong,
c_ssize_t, c_size_t, c_float, c_double)))

def calcsize(fmt, pack=None):
'''Compute size of a format string with arbitrary padding (defaults to native)'''
class _(Structure):
if pack is not None:
_pack_ = pack
_fields_ = [("", FMT_TO_TYPE[c]) for c in fmt]
return sizeof(_)

一旦定义,您就可以像这样计算填充或未填充的大小:

>>> calcsize("hl")     # Defaults to native "natural" alignment padding
16
>>> calcsize("hl", 1) # pack=1 means no alignment padding between members
10

关于Python struct calsize 与实际不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48425462/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com