Packing a ctypes struct containing bitfields.

Karthik karthik301176 at gmail.com
Thu Jun 18 21:06:25 EDT 2009


On Jun 18, 6:29 pm, Nick Craig-Wood <n... at craig-wood.com> wrote:
> Karthik <karthik301... 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 <n... at craig-wood.com> --http://www.craig-wood.com/nick

Oops, sorry about the missing __attribute__((packed)) - that was an
error of
omission.

Thank you, Nick :)

I'm looking at some C code that's using bitfields in structs, and I'm
writing
python code that "imports" these structs and messes around with them -
unfortunately,
I'm not at liberty to change the C code to not use bitfields.

Your solution works fine, so that's what I'm going to use.

Thanks,
Karthik.



More information about the Python-list mailing list