I have an 'n' Byte bytearray. This is same as one of the defined ctypes.Sturcture. I want to typecast this bytearray to this sturcture. so that I can access each of this member. How can I do that?
class ABC(Structure):
_fields_ = [("a", c_uint), ("b", c_ushort), ("c", c_ushort)]
class DEF(Structure):
_fields_ = [("abc", ABC), ("i", I)]
b = bytearray(b'\x88\x08\xc0\xf9\x02\x85\x10\x00\xcc')
s = DEF()
print(s.abc.a)
How do I get the the correct value of the above print statement?
You can use from_buffer on the desired type (rather than the object instance):
from ctypes import Structure, c_uint, c_ushort, c_uint8
class ABC(Structure):
_pack_ = 1
_fields_ = [("a", c_uint), ("b", c_ushort), ("c", c_ushort)]
class DEF(Structure):
_pack_ = 1
_fields_ = [("abc", ABC), ("i", c_uint8)]
def main():
b = bytearray(b'\x88\x08\xc0\xf9\x02\x85\x10\x00\xcc')
# check if bytearray can be applied to structure.
if len(b) < ctypes.sizeof(DEF):
print("error: bytearray is too short for DEF.")
return
s = DEF.from_buffer(b)
print("abc.a: {:#x}".format(s.abc.a))
print("abc.b: {:#x}".format(s.abc.b))
print("abc.c: {:#x}".format(s.abc.c))
print("i: {:#x}".format(s.i))
if __name__ == '__main__':
main()
Note that the structure must be packed accordingly, thus I used a _pack_ = 1 so the expected size of DEF structure is 9 bytes (4 + 2 + 2 + 1) rather than 12.
I also used c_uint8 for the DEF.i field as this is probably what you meant (I, in your example, is not a type).
Output:
abc.a: 0xf9c00888
abc.b: 0x8502
abc.c: 0x10
i: 0xcc
If you want the value in big endian (rather than the default little endian), change the endianness of the structure by using ctypes.BigEndianStructure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With