Re: Problem with alignment under Linux

Axel Seibert <[email protected]> Thu, 12 Apr 2012 23:05:14 +0200
Newsgroups gmane.comp.python.ctypes
Message-ID <[email protected]>
Hi, Andrew!
 
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 seems to not 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
> email: [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

------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2

_______________________________________________
ctypes-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ctypes-users