Re: Missing data when reading file using ctypes.Structure subclass

Malte Forkel <[email protected]> Thu, 03 Jan 2013 19:31:12 +0100
Newsgroups gmane.comp.python.ctypes
Message-ID <[email protected]>
Hello,

before all the answers start pouring in ;-), here is a test I ran in an
attempt to understand what's going on. The resulting offsets of some
fields look strange to me. But then, it may be just a lack of
understanding on my part...

This is my test:

  from ctypes import *

  fields64 = [
              ('first', c_uint64, 40),
              ('second', c_uint8, 7),
              ('third', c_uint8, 1),
              ('fourth', c_uint16, 16),
              ]

  fields32 = [
              ('first', c_uint32, 16),
              ('second', c_uint8, 7),
              ('third', c_uint8, 1),
              ('fourth', c_uint8, 8),
              ]

  class Test64(Structure):
      _fields_ = fields64

  class PackedTest64(Structure):
      _pack_ = 1
      _fields_ = fields64

  class Test32(Structure):
      _fields_ = fields32

  class PackedTest32(Structure):
      _pack_ = 1
      _fields_ = fields32

  for cls in Test64, PackedTest64, Test32, PackedTest32:
      print '%s, %d bytes, pack %s' % (cls.__name__, sizeof(cls()),
                                       getattr(cls, '_pack_', 'n/a'))
      for field, ctype, width in cls._fields_:
          print '%-8s %s' % (field, getattr(cls, field))

On Ubuntu 12.10 with
  Python 2.7.3 (default, Sep 26 2012, 21:53:58)
  [GCC 4.7.2] on linux2
the results are

  Test64, 8 bytes, pack n/a
  first    <Field type=c_ulonglong, ofs=0:0, bits=40>
  second   <Field type=c_ubyte, ofs=7:40, bits=7>
  third    <Field type=c_ubyte, ofs=7:47, bits=1>
  fourth   <Field type=c_ushort, ofs=6:48, bits=16>
  PackedTest64, 8 bytes, pack 1
  first    <Field type=c_ulonglong, ofs=0:0, bits=40>
  second   <Field type=c_ubyte, ofs=7:40, bits=7>
  third    <Field type=c_ubyte, ofs=7:47, bits=1>
  fourth   <Field type=c_ushort, ofs=6:48, bits=16>
  Test32, 4 bytes, pack n/a
  first    <Field type=c_ulong, ofs=0:0, bits=16>
  second   <Field type=c_ubyte, ofs=3:16, bits=7>
  third    <Field type=c_ubyte, ofs=3:23, bits=1>
  fourth   <Field type=c_ubyte, ofs=3:24, bits=8>
  PackedTest32, 4 bytes, pack 1
  first    <Field type=c_ulong, ofs=0:0, bits=16>
  second   <Field type=c_ubyte, ofs=3:16, bits=7>
  third    <Field type=c_ubyte, ofs=3:23, bits=1>
  fourth   <Field type=c_ubyte, ofs=3:24, bits=8>

Are the offsets of the second and third field of the 8 byte structures
really ok? I would think they should be 5:40 and 5:47 respectively, as
the offsets in the 4 byte structure suggest.

May be my problem is similiar to this issue:
http://bugs.python.org/issue6068 (ctypes is not correctly handling
bitfields backed by 64 bit integers on Windows)? Unfortenately I don't
have access to a version of Python including that patch. Could someone
who does run the above test?

Malte


------------------------------------------------------------------------------
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. ON SALE this month only -- learn more at:
http://p.sf.net/sfu/learnmore_122712