Solved

structure packing between compilers. Are they commited to anything ?

Posted on 2011-03-05
16
535 Views
Last Modified: 2012-05-11
Hi!

I am writing a DLL (C++). The DLL has a C API (there is a nice header file, which contains the structures).
Part of the API is structures to be passed In and Out.
Now, the users of my DLL may use many compilers (intel, gcc & microsoft - and also different version of the compilres).
How do I make sure that they all understand my structures "the same way" ?

Suppose I write the following line at the beggining of the header file:
#pragma pack(X)                // where x may be 1,2,4 or 8
and ten I write the following line at the end of the header file:
#pragma pack()
Will this do the job in 100% of the cases ?


Thanks zmau
0
Comment
Question by:zmau
  • 6
  • 4
  • 3
  • +2
16 Comments
 
LVL 84

Expert Comment

by:ozo
ID: 35045232
No
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35045256
I assume that you don't have endian issues across the platforms. Some pragma pack had a third parameter to handle this (which gcc ignores).

I assume that the struct are c-like POD struct.

I assume that you are not dereferencing pointers to data fields in the struct. That might cause problems if not especially careful.

I assume that you are not concerned about any performance penalties using pragma pack
     
Even with these assumptions, pragma pack is not in the C or C++ standard. I would not use it for that reason across multiple platforms or compilers.
0
 
LVL 1

Author Comment

by:zmau
ID: 35045891
So, what is the best way to handle this problem ?
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
LVL 1

Author Comment

by:zmau
ID: 35045903
phoffric, your assuptions are correct.
BTW, Intel, gcc and Microsoft compiler do "accept pragma pack".

one more issue :
Do these compilers "re-arrage" the data in the structure (i.e. put the last declared variable at the beggining address (for example)) ?


Thanks
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35055275
>> So, what is the best way to handle this problem ?
     I suppose that is another question that will elicit multiple opinions on the "best" way. I'll just jot down some opinions without claiming them to be the "best".
You could compile the DLL code for each target to generate a suitable dll.
You could textify (or use xml) the struct into a single text string.

You may be interested in reading this link:  DLL_Hell
      http://en.wikipedia.org/wiki/DLL_Hell
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35055321
>> one more issue :
>> Do these compilers "re-arrage" the data in the structure (i.e. put the last declared variable at the beggining address (for example)) ?
    I suppose that is another question also.

In my experience when debugging, I have never seen a rearrangement of struct members; and, I have never seen code which reliies on this experience. Experience in such matters in not important. There is nothing in the C++ standard which talks about the layout of POD-struct members. The access to these are through standard operators such as . and ->. In case you were thinking of trying some offset scheme, I would not suggest that if trying to be portable.

0
 
LVL 33

Expert Comment

by:sarabande
ID: 35057146
you could add a member to your structures which holds the size of the structure and must be set from sender. then the receiver can check for the size before accepting the buffer. that also is a check on expected alignment cause different alignment would result into different size.

generally each compiler has an option for packed alignment and as you need individual build tools anyhow, the setting for the packing shouldn't add less portability. i wouldn't set the alignment via pragma preprocessor statement but would use project or makefile options.

Sara
0
 
LVL 22

Expert Comment

by:NovaDenizen
ID: 35072544
I can't figure out why you care about how the struct members are laid out.

Are you using some kind of direct (zero-effort) conversion between structs and binary blobs used in interchange?  This is generally a bad idea.  Parse the interchange data into a struct, then serialize the struct back into a blob.  Very little effort is required.

Are you creating data structures that you want your API users to directly reference?  This is a bad idea.  What happens when you need to change the struct or add something to it?  It creates an unnecessarily intimate dependency between your dll and your users.  Instead have the users access the data structure through functions, so the details of the structure are hidden from them.  Encapsulation is your friend.
0
 
LVL 1

Author Comment

by:zmau
ID: 35075735
I m sorry that my question was not clear.
The DLL alraedy exists. It's functions have structures as part of the API.
For example :
typedef struct BlaBla
{
   int A:
   int B;
} BLA_BLA;

void func_1(BLA_BLA* ptr);

The question is what to do now ?
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35076079
>> I am writing a DLL
This is very clear. You have source code and are building a DLL, right?
So, just compile the source on each platform as suggested.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35076093
Even if the members A and B fall nicely into place in your tests on all platforms, do you expect that the executable statements in the binary DLL will work from one system to another?
0
 
LVL 33

Expert Comment

by:sarabande
ID: 35080982
for a structure with two int members you don't need to expect alignment issues (but endianess can play a role). different alignment happens when there are members of different size or array members with odd array lengths. for example a char[3] member and a short mixed with int members likely will give different aligment among different compilers.

Sara
0
 
LVL 1

Author Comment

by:zmau
ID: 35081493
Hi all

Thanks for the help.
There seems to be a misunderstanding.

The DLL does exist, and I do have it's source. Now I am reponsible for it (just recently).
The DLL works on Windows platforms (32 bit). The users of this DLL (NOT me) have an h file, a lib file and the actual DLL. The users call the DLL's functions (and basically they are happy).
The example above was just an example (The actual structures have also shorts and chars).


Probably the packing issue was not thought of in the past. Now, I have came across one user who had decided to compile it's source with packing of 1 (for unknown reasons). The result was that "the DLL did not work".
Now I have no control over my users. They can do whatever they want (use any compiler the compile their source). I am looking for a way to prevent such future issues (Without major changes).



Thanks again.

0
 
LVL 33

Accepted Solution

by:
sarabande earned 250 total points
ID: 35081695
as suggested you can add a size member into the struct which must be filled with sizeof(<structure>) by anyone and later can be checked when reading the structure.

many structures of WINAPI are made that way for example struct STARTUPINFO used for CreateProcess.

another method is to sort the member types by double, int, short, char and do all array sizes a multiple of 4 or add fillers (dummy members) so that each new type or array begins at a 32-bit offset.

that way even packed(1) structures should have same alignment what easily could be checked for one compiler.

Sara
0
 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 250 total points
ID: 35081791
>> The actual structures have also shorts and chars
To reduce the odds that packing will be a problem (this is not standard language talk and no guarantees), arrange the members from high width to low. So cluster all the doubles at the top, then floats, then longs, shorts, chars. Then add your own padding at the end so that the size of the struct is, say a multiple of 4 to 8 bytes long).

=====

When you provide a binary object, you also provide a contract w.r.t. the object. It includes the api, the installation and usage procedures. You may have forgotten to indicate your rules about compilation for usage with the DLL (e.g., do not pack).

For this one user, see if they will agree to modify their make file so that the modules that use your DLL they will not pack saying that the DLL requires no packing; and since it works, that is the way to handle this problem. If they insist, then you can offer to support their needs (up to you whether to charge) by customizing a special DLL (maybe with a name change or a folder change) that is packed and work with them to thoroughly test the new version.

For all other users, send them an amendment to the contract indicating the rules for compiling with usage of your DLL. They shouldn't mind since they are already working well with it.

Now you have two versions to maintain - one with and one without packing.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This article will show, step by step, how to integrate R code into a R Sweave document
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question