This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Alan.Ning
Recipients Alan.Ning
Date 2014-02-14.21:43:22
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1392414202.99.0.0705946156557.issue20629@psf.upfronthosting.co.za>
In-reply-to
Content
I am seeing a strange issue with bitfields and BigEndianStructure under Ubuntu 12.04 x64, Python 2.7.3.

This bug only occurs if I define my bitfields using c_uint. If I switch to c_ushort, it goes away.

Below is a simple code that highlights the problem. I have two structures - BitField1U and BitField2U. It is a union of a 4 bytes array and a bitfield definition.

Under Linux, by simply setting fields.a = 1 twice, it modifies the underlying byte array twice in a very different way. This behavior does not occur in Windows.

Output: Ubuntu 12.04x64 Python 2.7.3
20000000
20000020 <- problem
20000000
20000000

Output: Window 7 x64 Python 2.7.3
20000000
20000000
20000000
20000000

This bug was originally reported as a question in StackOverflow. 
http://stackoverflow.com/questions/21785874/python-ctypes-bitfield-windows-vs-linux


Source code:

import ctypes
import binascii

class BitField1(ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [
    ('a', ctypes.c_uint, 3),
    ('b', ctypes.c_uint, 1),
    ]

class BitField1U(ctypes.Union):
    _pack_ = 1
    _fields_ = [("fields", BitField1), 
        ("raw_bytes", ctypes.c_ubyte * 4)]

class BitField2(ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [
    ('a', ctypes.c_ushort, 3),
    ('b', ctypes.c_ushort, 1),
    ]

class BitField2U(ctypes.Union):
    _pack_ = 1
    _fields_ = [("fields", BitField2), 
        ("raw_bytes", ctypes.c_ubyte * 4)]

def printBytes(raw_bytes) :
    ba = bytearray(raw_bytes)
    print(binascii.hexlify(ba))
    
def printFields(fields) :
    print(fields.a),
    print(fields.b),
    print

b1 = BitField1U()
b2 = BitField2U()

# Simply set fields.a = 1 twice, and notice how the raw_bytes changes.

b1.fields.a = 1
printBytes(b1.raw_bytes)
b1.fields.a = 1
printBytes(b1.raw_bytes)

b2.fields.a = 1
printBytes(b2.raw_bytes)
b2.fields.a = 1
printBytes(b2.raw_bytes)
History
Date User Action Args
2014-02-14 21:43:23Alan.Ningsetrecipients: + Alan.Ning
2014-02-14 21:43:22Alan.Ningsetmessageid: <1392414202.99.0.0705946156557.issue20629@psf.upfronthosting.co.za>
2014-02-14 21:43:22Alan.Ninglinkissue20629 messages
2014-02-14 21:43:22Alan.Ningcreate