ctypes and byte order
Peter Otten
__peter__ at web.de
Thu Jun 18 08:24:03 EDT 2015
Jean-Michel Pichavant wrote:
> ----- Original Message -----
>> From: "Peter Otten" <__peter__ at web.de>
>> becomes
>>
>> $ cat be2.py
>> import ctypes, sys
>>
>> iarray_be = ctypes.c_uint32.__ctype_be__*5
>>
>> class Foo_be(ctypes.BigEndianStructure):
>> _fields_ = [('bar', iarray_be)]
>>
>> print sys.version
>> f_be = Foo_be((0,1,2,3,0x11223344))
>> print hex(f_be.bar[4])
>>
>> $ python be2.py
>> 2.7.6 (default, Mar 22 2014, 22:59:56)
>> [GCC 4.8.2]
>> 0x11223344L
>>
>> which might do what you want.
>
> Brilliant !
>
> I've tested it and it yields the exact same results (binary file content
> wise) than my "workaround" structure. But that's way better since my
> actual structure is more complex and arrays will be required.
>
> Though I'm slightly puzzled by the ctypes author(s) choice, this is not
> documented and requires to peek into the source code. Dunder attributes
> are rarely part of an interface.
On further reflection it dawned on me that what may have made this work is
passing in the tuple instead of an array:
>>> import ctypes
>>> array = ctypes.c_uint32 * 3
>>> class B(ctypes.BigEndianStructure):
... _fields_ = [("bar", array)]
...
>>> b = B((1,2,3))
>>> b.bar
<ctypes._endian.c_uint_be_Array_3 object at 0x7f87700798c0>
>>> b.bar[2]
3L
>>> b = B(array(1,2,3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: incompatible types, c_uint_Array_3 instance instead of
c_uint_be_Array_3 instance
Oops...
So the only thing that doesn't work transparently is initialising a data
structure (or at least array) from its "other-endian" twin.
More information about the Python-list
mailing list