Search code examples
pythonstructalignmentctypes

python ctypes pragma pack for byte aligned read


I have a C++ application with below structure written to file. Now I need to unmarshal them using python, The basic problem here is how to reflect the pragma pack option in python.

C++ Structure

#pragma pack(1)
struct abc  
{  
unsigned char r1;  
unsigned char r2;  
unsigned char p1;  
unsigned int id;  
};  
#pragma pack()

Now, the structure size is 7 not 8,this data is written into a data file. How do I retrieve this data using python.

Note :
1. I am using ctypes, and the above structure is a sample structure.


ctypes uses the native byte order for Structures and Unions. To build structures with non-native byte order, you can use one of the BigEndianStructure, LittleEndianStructure, BigEndianUnion, and LittleEndianUnion base classes. These classes cannot contain pointer fields


The above information from python docs, does not delve into details.


Solution

  • You can change the packing in ctypes as described here

    By default, Structure and Union fields are aligned in the same way the C compiler does it. It is possible to override this behavior be specifying a pack class attribute in the subclass definition. This must be set to a positive integer and specifies the maximum alignment for the fields. This is what #pragma pack(n) also does in MSVC.

    For your example this would be:

    from ctypes import *
    
    class abc(Structure):
        _pack_ = 1
        _fields_ = [
            ('r1',c_ubyte),
            ('r2',c_ubyte),
            ('p1',c_ubyte),
            ('id',c_uint)]