4

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?

1
  • I guess you could use the s format specifier (which generates a single value) and re-unpack that value as integers/shorts/whatever. But I don't know if that qualifies as a "better" way though Commented Aug 31, 2018 at 14:03

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

That’s too bad that there’s not a built-in way to do this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.