Peter Gordon
Peter Gordon

Reputation: 15

Python initialise Struct

I have a block of memory with binary data. The block was created with ctypes.create_string_buffer, so the data is mutable, and accessible as an array.

Each 32 bits are made up of a pair, a 20 bit unsigned integer, and a 12 bit unsigned integer.

I want to access the nth element pair, and change the values in the memory block.

I have a structure:

from ctypes import *
class Int(Structure):
    _fields_ = [("first",  c_uint, 20),
                ("second",  c_uint, 12)]

How do I populate the Structure from my data? Is there a C like pointer I can set to point the structure at my data?

Upvotes: 1

Views: 75

Answers (1)

Brian Campbell
Brian Campbell

Reputation: 332836

You can create an array type of your Int by multiplying your structure type by its length; here I'm using 5 as an example, you can use whatever length you need:

IntArray5 = Int * 5
arr = IntArray5()

If you need to use different lengths each time, there's no need to name the type, you can just use:

arr = (Int * 5)()

Then rather than passing your string buffer to the C function, reading into that, and needing to do a conversion, it's probably best if you just pass your array into the function that will populate it:

myfunc = libfoo.myfunc
myfunc(arr, len(arr))

Now you should be able to access the elements of arr:

print arr[0].first
print arr[0].second

However, if for some reason you can't pass that array in to the function directly, and instead need to take an existing string buffer and produce an array of Int that shares the buffer, you can use from_buffer as eryksun suggests:

arr = (Int * 5).from_buffer(buff)

Or if you wanted to copy into a new array rather than sharing the underlying buffer:

arr = (Int * 5).from_buffer_copy(buff)

Upvotes: 2

Related Questions