FAQ: how to vary the byte offset of a field of a ctypes.Structure

Larry Bates larry.bates at websafe.com
Thu May 31 14:20:38 EDT 2007


p.lavarre at ieee.org wrote:
> How do I vary the byte offset of a field of a ctypes.Structure?
> 
> How do I "use the dynamic nature of Python, and (re-)define the data
> type after the required size is already known, on a case by case
> basis"?
> 
> \\\
> 
> For example, suppose sometimes I receive the value '\x03hi' + \x04bye'
> for the struct:
> 
>         class Struct34(ctypes.Structure):
>                 _pack_ = 1
>                 _fields_ = [('first', 3 * ctypes.c_ubyte),
>                         ('second', 4 * ctypes.c_ubyte)]
> 
> but then sometimes instead I receive the value '\x05left' + \x06right'
> for the struct:
> 
>         class Struct56(ctypes.Structure):
>                 _pack_ = 1
>                 _fields_ = [('first', 5 * ctypes.c_ubyte),
>                         ('second', 6 * ctypes.c_ubyte)]
> 
> Thus in general I receive (0xFF ** 2) possible combinations of field
> lengths.
> 
> ///
> 
> How do I declare all those hugely many simply regular combinations as
> one CTypes.structure?
> 
> I also need to do series of 3 or 4 or 5 strings, not just 2 strings.
> But always the byte offsets of the subsequent fields vary when the
> byte sizes of the preceding fields vary. The byte size of the
> enclosing packed struct varies as the length of the packed bytes it
> contains.
> 
> The errors I get as I try techniques that don't work include:
> 
> AttributeError: '_fields_' must be a sequence of pairs
> AttributeError: _fields_ is final
> ValueError: Memory cannot be resized because this object doesn't own
> it
> TypeError: incompatible types, c_ubyte_Array_2 instance instead of
> c_ubyte_Array_1 instance
> 
> How do I change the offset of a field of a ctypes.Structure?
> 
> Is the answer to contribute to the next version of CTypes? Or is this
> feature already supported somehow?
> 
> Curiously yours, thank in advance,
> 

How about something like:

class fooStruct(ctypes.Structure):
    _pack_ = 1
    _fields_=[]
    def __init__(self, fields):
        self._fields_=fields
        ctypes.Structure.__init__(self)

a=fooStruct([('first', 3*ctypes.c_ubyte),
             ('second', 4*ctypes.c_ubyte)])

print a._fields_


-Larry



More information about the Python-list mailing list