New submission from higstar <adr...@higstar.com>: Structure fails to correctly cast from a 2 byte bitfield.
>From my very limited investigation, is looks like when using a member type of less than the total size of the structure (or at least the size of any byte boundaries) the casting is not done correctly? I created this test.py and appended the results below: --- import ctypes import time class closest_fit(ctypes.BigEndianStructure): # _pack_ = 1 # aligned to 8 bits, not ctypes default of 32 _fields_ = [ ("Data0", ctypes.c_ubyte, 7), ("Data1", ctypes.c_ubyte, 8), ] class all_ulong(ctypes.BigEndianStructure): # _pack_ = 1 # aligned to 8 bits, not ctypes default of 32 _fields_ = [ ("Data0", ctypes.c_ulonglong, 7), ("Data1", ctypes.c_ulonglong, 8), ] def castbytes(type): buffer = (ctypes.c_byte * 2)() buffer[0] = 0x55 buffer[1] = 0x55 return ctypes.cast(ctypes.pointer(buffer), ctypes.POINTER(type)).contents def print_members(test): print("Data0 is 0x%X, Data1 is 0x%X for %s"%(test.Data0, test.Data1, test.__class__.__name__)) test_classes = [ closest_fit, all_ulonglong] Failed = False tests = [castbytes(type) for type in test_classes] for test in tests: print_members(test) if not tests[0].Data0 == tests[1].Data0: Failed = True if not tests[0].Data1 == tests[1].Data1: Failed = True if Failed: print("Failed") else: print("Passed") --- >c:\python25\python.exe test.py Data0 is 0x2A, Data1 is 0x55 for closest_fit Data0 is 0x2A, Data1 is 0xAA for all_ulonglong Failed >c:\python26\python.exe test.py Data0 is 0x2A, Data1 is 0x55 for closest_fit Data0 is 0x2A, Data1 is 0xAA for all_ulonglong Failed >c:\python30\python.exe test.py Data0 is 0x2A, Data1 is 0x55 for closest_fit Data0 is 0x2A, Data1 is 0xAA for all_ulonglong Failed As you can see the second member Data1, should be 0xAA, however when using c_ubyte types for members the value is not offset by one bit. As you can see using c_ulonglong for all members avoids this issue, however this results in a read only structure (see Issue 6068). I am using structures to cast CAN messages which are 8 bytes, with very funky bit fields crossing all sorts of byte boundaries, so I essentially expected that ctypes would provide a method for an arbitrary bit field definition for use within python. Hopefully this is just my bad ctypes driving, or a simple fix. ---------- assignee: theller components: ctypes messages: 88111 nosy: higstar, theller severity: normal status: open title: casting error from ctypes array to structure versions: Python 2.5, Python 2.6, Python 3.0 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue6069> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com