assignment of Array elements in ctypes Structure

Question:

What’s the idiomatic way of assigning array elements in a ctypes.Structure? For example, given:

from ctypes import Structure, c_float

class Foo(Structure):
    _fields_ = (
        ('arr', c_float*3),
    )

values = [1.1, 2.2, 3.3]

I expected to be able to just do:

foo = Foo()
foo.arr = values

but this complains about type mismatch.

TypeError: expected c_float_Array_3 instance, got list

I’m adding an answer showing what I’ve gone with, but would be interested to know of any more definitive answers.

Asked By: Sam Mason

||

Answers:

The solution I’ve gone with is to use:

foo.arr = type(foo.arr)(*values)

While a more verbose option would be to do:

for i, v in enumerate(values):
  foo.arr[i] = v

Note that both options allow values to be shorter (i.e. zero to three elements), with missing entries padded with zeros. An error will be raised if the values contains too many entries. This is consistent with array initialization in C and happens to be what I want my code to do, but might be too liberal for other cases.

Update: after looking into the source code I’ve noticed that slice assignment allows sequence objects to be used, e.g.:

foo.arr[:] = values

which allows lists to be used without creating a temporary object. Re-reading the docs, I see:

Array elements can be read and written using standard subscript and slice accesses

which seems to suggest that this is the intended usage.

Answered By: Sam Mason

foo.arr = tuple(values) seems to work

Answered By: Unanimous
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.