Axel Seibert | 13 May 10:27 2012

Re: Problem with alignment under Linux

Dear list!


[I sent this email out a month ago, but have not received any feedback yet. Let me repost my email in the hope that somebody can help me out with that. The current situation makes it impossible for my project to continue under Linux.]

 

It’s been two months since we had our discussion. I have tried to follow your suggestion:

-        check each member of a union for a type which requires the 8 byte alignment and mark that union appropriately if such a type is found (ie double or long long);

-        check each member of a struct for a type which requires the 8 byte alignment, and if such a member is encountered insert appropriate padding before the member

and then you suggested a code snippet.

 

The executive summary is: This approach (at least in the current implementation) seems not to work.

 

I believe for Structures, it could work.

However, for Unions I found the following issues:

1.     in your example below, you suggest a function align_union(union_class), which could be called in _init_. This could be used when my code instantiates such unions; but what about unions that are created by the server side that I’m only trying to read?

2.     Therefore, I changed the sample code; as I know which unions need to be aligned differently, I guess I don’t need this function, and could set class._alignment immediately, e.g.:

class BMCUnion(Union):

    _alignment = 8

 

Unfortunately, this also seems to not work, and I guess, the answer lies here:

 

class N13ARValueStruct3DOLLAR_1E(BMCUnion):

    pass

>>> a=N13ARValueStruct3DOLLAR_1E()

>>> a._alignment

8

>>> alignment(a)

4

 

What am I missing? Are there other variations on this theme which could lead to a solution?

 

Thanx for your input!
Axel

 

Am 14.02.2012 um 09:34 schrieb Andrew MacIntyre:

I think the comment in the documentation has to be a red herring, as it would make that compiler noncompliant with the Linux i386 ABI by default which would probably cause all sorts of problems compiling other software.

 

It seems to me that you will need to do several things:

-          check each member of a union for a type which requires the 8 byte alignment and mark that union appropriately if such a type is found (ie double or long long);

-          check each member of a struct for a type which requires the 8 byte alignment, and if such a member is encountered insert appropriate padding before the member.

 

The approach that occurs to me is to use an attribute which can be tested for using hasattr() (or AttributeError if you prefer exceptions rather than look before leap).

 

Perhaps something along the lines of (untested! and not necessarily all encompassing):

 

                ...

                from ctypes import *

 

                ...

 

                # this foreign DLL is built with –malign_double

c_double._alignment = 8

                c_long_long._alignment = 8

 

                ...

 

                # check a Union for members requiring non-standard alignment

                def align_union(union_class):

                                for n, t in union_class._fields_:

                                                if hasattr(t, ‘_alignment’):

                                                                union_class._alignment = t._alignment

                                                                break

 

                # patch the ‘fields’ sequence of a ctypes Structure by inserting

                # dummy fields to achieve required alignment

                def pad_struct(fields):

                                result = []

                                size = 0

                                for n, t in fields:

                                                if hasattr(t, ‘_alignment’):

                                                                padding = size % t._alignment

                                                                if padding:

                                                                                padding = t._alignment – padding

                                                                                result.append((‘’, c_char * padding))

                                                                                size += padding

                                                size += sizeof(t)

                                                result.append((n, t))

                                return result

 

                ...

 

                class U(Union):

 

                                _fields_ = ((‘a’, c_long),

                                                                (‘b’, c_double))

 

                                def __init__(self):

                                                align_union(self)

                                                Union.__init__(self)

 

                class S(Structure):

                                _fields_ = pad_struct(((‘c’, c_long),

                                                                                (‘d’, U)))

 

                ...

 

-------------------------> "These thoughts are mine alone!" <---------

Andrew MacIntyre           Operations Branch

tel:   +61 2 6219 5356     Communications Infrastructure Division

fax:   +61 2 6253 3277     Australian Communications & Media Authority

 

From: Axel Seibert [mailto:axel <at> globonaut.org] 
Sent: Tuesday, 14 February 2012 6:34 AM
To: ctypes-users <at> lists.sourceforge.net
Subject: Re: [ctypes-users] Problem with alignment under Linux [SEC=UNCLASSIFIED]

 

Hi, Andrew!

 

According to http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html, "aligned" is the attribute to look for.  There is another possibility that occurs to me: the use of the gcc option "-malign-double" forcing doubles to be 8 byte aligned when building the library.

 

This is the hint that brought me in the right direction; looking at one of the supplied examples shows that the Makefile under Linux calls the compiler with the following arguments:

 

-malign-double

 

And the documentation says:

        Configure the compiler as follows: Structure member alignment: 8 bytes (default)

 

In other words, the software supplier requires this for whatever reasons. What can we now deduct from this for my problem?

 

Thanx again for your help,

Axel

 

 

NOTICE: This email message is for the sole use of the intended recipient(s) 
and may contain confidential and privileged information. Any unauthorized 
review, use, disclosure or distribution is prohibited. If you are not the 
intended recipient, please contact the sender by reply email and destroy all 
copies of the original message.

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users
Ion Padilla | 16 May 12:01 2012
Picon

Problem with a c structure

Hello,

I am trying to create an application that uses this structure:

class ISD_STATION_INFO_TYPE (ctypes.Structure):
    _fields_=[('ID',ctypes.c_ulong)
              ,('State',ctypes.c_long)
              ,('Compass',ctypes.c_long)
              ,('InertiaCube',ctypes.c_long)
              ,('Enhancement',ctypes.c_ulong)
              ,('Sensitivity',ctypes.c_ulong)
              ,('Prediction',ctypes.c_ulong)
              ,('AngleFormat',ctypes.c_ulong)
              ,('TimeStamped',ctypes.c_long)
              ,('GetInputs',ctypes.c_long)
              ,('GetEncoderData',ctypes.c_long)
              ,('CompassCompensation',ctypes.c_byte)
              ,('ImuShockSuppression',ctypes.c_byte)
              ,('UrmRejectionFactor',ctypes.c_byte)
              ,('bReserved2',ctypes.c_byte)
              ,('CoordFrame',ctypes.c_ulong)
              ,('AccelSensitivity',ctypes.c_ulong)
              ,('fReserved1',ctypes.c_float)
              ,('fReserved2',ctypes.c_float)
              ,('TipOffset',ctypes.c_float*3)
              ,('fReserved3',ctypes.c_float)
              ,('GetCameraData',ctypes.c_long)
              ,('GetAuxInputs',ctypes.c_long)
              ,('GetCovarianceData',ctypes.c_long)
              ,('GetExtendedData',ctypes.c_long)]

that comes from this structure in c:

typedef struct
{
    DWORD   ID; 
    Bool    State;            
    Bool    Compass; 
    LONG    InertiaCube;    
    DWORD   Enhancement;  
    DWORD   Sensitivity;      
    DWORD   Prediction;       
    DWORD   AngleFormat;     
    Bool    TimeStamped;       
    Bool    GetInputs;         
    Bool    GetEncoderData;     
    BYTE    CompassCompensation;    
    BYTE    ImuShockSuppression;
    BYTE    UrmRejectionFactor;
    BYTE    bReserved2;
    DWORD   CoordFrame;     
    DWORD   AccelSensitivity;
    float   fReserved1;   
    float   fReserved2;
    float   TipOffset[3];  
    float   fReserved3;
    Bool    GetCameraData;
    Bool    GetAuxInputs;    
    Bool    GetCovarianceData;
    Bool    GetExtendedData; 
}
ISD_STATION_INFO_TYPE;

Using this structure I want to call to a function to get the structure using byref, change the field GetInputs to TRUE and set it again. The call to the function is not working and the variable after the call returns setted to FALSE. What I am doing wrong? Is there any compatibility problem with the structure? Here is the code:

     config=ISD_STATION_INFO_TYPE()
     isenseWrapper.ISD_GetStationConfig(handle,ctypes.byref(config),WAND_STATION,1)
     config.GetInputs = not config.GetInputs
     isenseWrapper.ISD_SetStationConfig(handle,ctypes.byref(config),WAND_STATION,1)

PS: The first call works and I get the structure correctly filled, is not empty

Thanks in advantage

Regards

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
ctypes-users mailing list
ctypes-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ctypes-users

Gmane