I would like to construct an unsigned 32-bit int using Python3 ctypes bit field, as follows:
c_uint = ctypes.c_uint32
class Flags_bits(ctypes.LittleEndianStructure):
_fields_ = [
("a", c_uint, 4),
("b", c_uint, 4),
("c", c_uint, 4),
("d", c_uint, 4),
("e", c_uint, 4),
("f", c_uint, 4),
("g", c_uint, 4),
("h", c_uint, 4)]
When I substitute Flags_bits
with specific integer values,
aa = Flags_bits(1,2,3,4,5,6,7,8)
print(hexlify(aa).decode('utf-8'))
The output is
21436587
I was expecting an output like
87654321 # binary of 1000 0111 0110 0101 0100 0011 0010 0001
Since Little-endian constructs bits starting with the low bit. How can I obtain the expected output? Is there anything I did wrong? Could someone be so kind to help me? Thanks in advance!
It IS stored little-endian. The binascii.hexlify
function reads the value as a set of bytes, and returns a string of those bytes. It's not treating them as an integer. As bytes, the values are 21 43 65 87. Unless you treat a set of bytes as a multi-byte unit, endianness does not apply.
If you want to see the value as a 32-bit integer, do this, which results in 87654321:
import struct
...
aa = Flags_bits(1,2,3,4,5,6,7,8)
aa_int = struct.unpack('I',aa)[0]
print(hex(aa_int))
Bitfield structures are problematic, even in C. Honestly, in many cases it's way easier to shift and mask:
def Flags_bits(*data):
val = 0
for n in reversed(data):
val = (val << 4) | n
return val