While the struct module makes handling C-like structures containing scalar values very simple, I don’t see how to sensibly handle structs which contain arrays.
For example, if I have the following C struct:
struct my_struct {
int a1[6];
double a2[3];
double d1;
double d2;
int i1;
int i2;
int a3[6];
int i3;
};
and want to unpack its values and use the same variables (a1, a2, a3, d1, d2, i1, i2, i3) in Python, I run into the problem that struct just gives me every value in a tuple individually. All information about which values are supposed to be grouped in an array is lost:
# doesn’t work!
a1, a2, d1, d2, i1, i2, a3, i3 = struct.unpack(
'6i3dddii6ii', b'abcdefghijklmnopqrstuvwxy' * 4
)
Instead, I have to slice and pull apart the tuple manually, which is a very tedious and error-prone procedure:
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]
Is there any better way of handling arrays with struct?
You can use construct library, which is pretty much wraps struct module and makes parsing and building binary data more convenient.
Here is a basic example:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With