
At 11:40 PM -0700 7/30/10, Sean Perry wrote:
I would like to read C structs that have been written to disk as binary data. Is there a reference on doing this somewhere. The IO is not too hard, but how do I mimic the C struct in Haskell and still honor the exact sizes of the various struct members?
At 9:11 AM +0100 7/31/10, Stephen Tetley wrote:
Hi Sean
Commonly people would use Data.Word and Data.Int to get sized integrals. There's no corresponding sized types for floats - if you're lucky your serialized C Structs won't use floats otherwise you'll have to dig out a reference manual to see how they are laid out.
To actually read C-structs Data.Binary.Get should provide the primitives you need (getWord8, getWord16le, getWord16be, ...), you'll then have to assemble a parser using these primitives to read your struct.
You might have to pay some attention to alignment - the C struct might be laid out with elements on byte boundaries (usually 4-byte) rather than directly adjacent. I suspect alignment is compiler dependent, its a long time since I looked at this but I believe C99 has pragmas to direct the compiler on alignment.
Best wishes
Stephen
I would recommend using hsc2hs instead, as it avoids having to emulate the C compiler, which is tedious and error-prone. (See section 10.3 of the GHC User's Guide.) In a nutshell, you write (the necessary parts of) your program in a modestly extended Haskell. In an .hsc file you can #include C header files (no need to duplicate that code in Haskell!) and bring selected pieces of the C world (types, field offsets, ...) into Haskell. The hsc2hs translator actually creates a C program from your .hsc file that, when executed, writes your .hs file, incorporating the needed knowledge from C land. Dean