Packing a ctypes struct containing bitfields.

Nick Craig-Wood nick at craig-wood.com
Thu Jun 18 15:29:32 CEST 2009


Karthik <karthik301176 at gmail.com> wrote:
>  Hello Everybody,
> 
>  I'm trying to create a packed structure in ctypes (with one 64-bit
>  element that is bitfielded to 48 bits),
>  unsuccessfully:
> 
> ===================================
>  from ctypes import *
> 
>  class foo (Structure):
>      _pack_ = 1
>      _fields_ = [
>          ("bar",    c_ulonglong, 48),
>      ]
> 
>  print("sizeof(foo) = %d" % sizeof(foo))
> ===================================
>  I'm expecting that this should print 6 - however, on my box, it prints
>  8.
> 
>  The following piece of C code, when compiled and run, prints 6, which
>  is correct.
> ===================================
>  struct foo {
>      unsigned long long bar: 48;
>  };
> 
>  printf("sizeof(foo) = %d", sizeof(foo));
> ===================================
> 
>  So... what am I doing wrong?

I compiled and ran the above with gcc on my linux box - it prints 8
unless I add __attribute__((__packed__)) to the struct.

I'm not sure that using bitfields like that is a portable at all
between compilers let alone architectures.

I'd probably do

from ctypes import *

class foo (Structure):
    _pack_ = 1
    _fields_ = [
        ("bar0",    c_uint32),
        ("bar1",    c_uint16),
    ]
    def set_bar(self, bar):
        self.bar0 = bar & 0xFFFFFFFF
        self.bar1 = (bar >> 32) & 0xFFFF
    def get_bar(self):
        return (self.bar1 << 32) + self.bar0
    bar = property(get_bar, set_bar)

print "sizeof(foo) = %d" % sizeof(foo)
f = foo()
print f.bar
f.bar = 123456789012345
print f.bar

Which prints

sizeof(foo) = 6
0
123456789012345

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list