Re: Problem with alignment under Linux [SEC=UNCLASSIFIED]

"Andrew MacIntyre" <[email protected]> Tue, 14 Feb 2012 08:34:28 +0000
Newsgroups gmane.comp.python.ctypes
Message-ID <A1E4E9D08D14924498E135FB4441EE8D18FEC230@act01exmbx01vp.internal.govt>
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
email: [email protected]<mailto:[email protected]>            http://www.acma.gov.au/

From: Axel Seibert [mailto:[email protected]]
Sent: Tuesday, 14 February 2012 6:34 AM
To: [email protected]
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/ctypes-users