Reputation: 11354
I am trying to pass an array of unions via ctypes to my C++ DLL and I am fairly new to Python. Is there a shorthand way of constructing them, for example:
class MyValue(Union):
_fields_ = [
("ftNone" , c_void_p),
("ftString", c_char_p),
("ftInt" , c_int ),
("ftBigInt", c_long ),
("ftFloat" , c_char_p)
]
MyValues = MyValue * 20
CMethod(MyValues(
('ftInt' = 12),
('ftString' = 'testing')
))
Or is there a better way of doing this?. I basically want to pass an array of mixed types to my DLL.
Upvotes: 0
Views: 196
Reputation: 34260
A ctypes array is initialized with positional arguments. An initial value can be a ctypes data object, a Python object compatible with a simple data type (for an array of simple types such as c_int * 20
), or a tuple of positional arguments used to create a temporary instance of the array's data type to be copied (memcpy
) into the array.
Since you need a keyword argument to select the proper converter, you'll have to either call MyValue
to manually create the temporary instance, or call setattr
on each item of an unitialized array. For the former, you can use a generator expression combined with *
and **
unpacking (see the tutorial):
values = [
('ftInt', 12),
('ftString', 'testing'),
]
arr = MyValues(*(MyValue(**{k: v}) for k, v in values))
And here's an alternative using setattr
to update the array in a loop:
arr = MyValues()
for item, value in zip(arr, values):
setattr(item, *value) # note the * unpacking
It would be nice to add support for a keyword argument dict in _PyCData_set
(Modules/ctypes/_ctypes.c).
Upvotes: 1