Mark Dickinson wrote:
On Oct 20, 10:51 pm, Tommy Grav <tg...@pha.jhu.edu> wrote:
I have created a binary file that saves this struct from some C code:

   struct recOneData {
          char label[3][84];
          char constName[400][6];
        double timeData[3];
      long int numConst;
        double AU;
        double EMRAT;
      long int coeffPtr[12][3];
      long int DENUM;
      long int libratPtr[3];
      };

I try to read this file with python (ActiveState 2.6.3 on x86_64 Mac OS X 10.6.1) using the code below the hdrData and constNData are fine, while from the timeData onwards there are obvious problems. The code below works fine for a 32bit binary read with i386 python 2.5.2. Does anyone know what the proper format of a C double and long int is for a x86_64
binary?

As others have said, it depends on the platform.  But on OS X 10.6,
and on most 64-bit Linuxes that I've met, I'm fairly sure that
sizeof(long int) =sizeof(double) == 8.  In contrast, 64-bit
Windows on the same hardware will probably have sizeof(long int) =4.

     def read_header(cls):
         hdrData =84s"*3
         constNData =6s"*400

I'm confused:  why is this not "400s"*6 rather than "6s"*400?
Doesn't constName[400][6] mean 6 lots of constName[400]?
Similarly for "84s"*3.  This might be making a difference to
the padding.

[...]

--
Mark

I don't know much about the 64 bit Unix platforms, since 64bits was just a dream last time I used Unix.

But I'd guess that your problem is that double will be aligned to 8 bytes on some platforms. Since your characters don't add up to a multiple of 8, you'd have some paddding between them.


When you get to define your own file format, the old advice was to:
1) use text form if possible, where the endianness and the alignment are non-issues. 2) If you must use binary data, directly stored, then put the largest-aligned items at the beginning of the struct, and work down to the smallest alignments. That way there is never any padding, except at the end of the struct. For that, add a dummy character field of a size appropriate to bring the size to a multiple of the largest alignment, generally 8. You'd still have to worry about endianness, but at least padding goes away.

Incidentally, though it doesn't affect the padding issues, I believe you have the meaning of constName[400][6] backwards. This refers to 400 strings of 6 bytes each. In C, the definitions are in row-major order.

DaveA

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to