doc on accessing C struct binary data

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?

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

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

On Sat, 2010-07-31 at 17:05 -0400, Dean Herington wrote:
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
Sounds like what I am looking for, thanks!
participants (3)
-
Dean Herington
-
Sean Perry
-
Stephen Tetley