Python:使用结构模块处理包含数组的结构

Python: Handling structs containing arrays with the struct module

虽然 struct 模块使处理包含标量值的类 C 结构变得非常简单,但我看不出如何明智地处理包含数组的结构。

例如,如果我有以下 C 结构:

struct my_struct {
    int a1[6];
    double a2[3];
    double d1;
    double d2;
    int i1;
    int i2;
    int a3[6];
    int i3;
};

并希望解压其值并使用相同的变量(a1a2a3d1d2i1, i2, i3) 在 Python 中,我 运行 遇到的问题是 struct 只是分别给我一个元组中的每个值。所有关于哪些值应该分组在数组中的信息都丢失了:

# doesn’t work!
a1, a2, d1, d2, i1, i2, a3, i3 = struct.unpack(
    '6i3dddii6ii', b'abcdefghijklmnopqrstuvwxy' * 4
)

相反,我必须手动对元组进行切片和分离,这是一个非常繁琐且容易出错的过程:

t = struct.unpack('6i3dddii6ii', b'abcdefghijklmnopqrstuvwxy' * 4)
a1 = t[:6]
a2 = t[6:9]
d1, d2, i1, i2 = t[9:13]
a3 = t[13:19]
i3 = t[19]

有没有更好的方法来处理 struct 的数组?

您可以使用 construct library,它几乎包装了 struct 模块,使解析和构建二进制数据更加方便。

这是一个基本示例:

import construct

my_struct = construct.Struct(
    "a1" / construct.Array(6, construct.Int32sl),
    "a2" / construct.Array(3, construct.Float64l),
    "d1" / construct.Float64l,
    "d2" / construct.Float64l,
    "i1" / construct.Int32sl,
    "i2" / construct.Int32sl,
    "a3" / construct.Array(6, construct.Int32sl),
    "i3" / construct.Int32sl
)



parsed_result = my_struct.parse(b'abcdefghijklmnopqrstuvwxy' * 4)

# now all struct attributes are available
print(parsed_result.a1)
print(parsed_result.a2)
print(parsed_result.i3)


assert 'a1' in parsed_result
assert 'i3' in parsed_result