[Haskell-cafe] Re: Begginer question about alignment in Storable

Michael D. Adams mdmkolbe at gmail.com
Thu Nov 20 09:06:16 EST 2008


On Wed, Nov 19, 2008 at 1:01 PM, Mauricio <briqueabraque at yahoo.com> wrote:
>> If you are using hsc2hs (if you are using Cabal this is easy; just
>> rename the file to *.hsc and Cabal will take care of the rest), then
>> there is a macro for making this easier and so you don't have to think
>> about it. (...)
>
> Well, after reading FFI addendum, I'm using
> my loyal text editor. Am I supposed to use
> something else? Is there something a tool like
> hsc2hs or cabal setup can do that is more
> portable than what I could write myself? Where
> should I learn about that?

Not necessarily more portable but definitely easier to maintain. The
GHC manual contains [1] some sparse info on how to use hsc2hs (it
seems to be built in to GHC).  But the major advantage of hsc2hs is
that if your C struct changes or you use a different C compiler, the
allignment and size as well as the offsets used in peek and poke will
still be correct since the compiler will calculate it for you.  (Of
course hsc2hs can't help you if fields are added or removed from the
struct.)  So for example suppose you had a struct like:

typedef struct {
  int a;
  char b;
  double c;
} my_struct;

And you wanted to write a storable instance.  With hsc2hs you would
write it like this:

instance Storable Struct where
  alignment _ = #{alignment my_struct}
  sizeOf _ = #{size my_struct}
  peek ptr = do
    a <- #{peek my_struct, a} ptr
    b <- #{peek my_struct, b} ptr
    c <- #{peek my_struct, c} ptr
    return (MyStruct a, b, c)
  poke ptr (MyStruct a b c) = do
    #{poke my_struct, a} ptr a
    #{poke my_struct, b} ptr b
    #{poke my_struct, c} ptr c

Note that I didn't have to worry myself about what padding the
compiler might put between for example "a" and "b" or what size "int"
is.  When I wrote the hpapi [2] package using hsc2hs was a life saver
for these sorts of things.  (You might look in those sources for
examples.)

Regarding "cabal setup", that is only really needed if you are
intending to build a package to distribute to other people.  But if
you do want to distribute it (e.g. on the hackage repository) cabal is
the way to go.  I only mentioned it because if you are already using
cabal then cabal automatically figures out that *.hsc files need to be
sent through hsc2hs.  (GHC may also do this, I haven't tried.)  What
this means is that once you spend the time to set up a cabal file for
your project, the extra work for you as a developer to enable using
hsc2hs is almost nothing; you just have to rename the file.  For
project structures that cabel can understand natively (e.g. you just
have a colection of Haskell, Alex, Happy, Hsc2hs, etc. files), I
highly recommend using it.  It is one of the simplest to use build
system I've seen.  (I don't have a good link for learning cabal;
you'll have to google around (e.g. "haskell cabal") for info.)

Michael D. Adams

[1] http://www.haskell.org/ghc/docs/latest/html/users_guide/hsc2hs.html
[2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hpapi


More information about the Haskell-Cafe mailing list