[Haskell-cafe] FFI basics

Evan Laforge qdunkan at gmail.com
Mon Feb 26 16:02:57 EST 2007


... and now I have more questions.  Maybe it would be better if I just
asked them on the mailing list, and then incorporated the answers into
the wiki myself.

Question #1 is compiling FFI using modules.  I'd like to use ghc
--make for the speed and convenience, but obviously it doesn't know
how to compile the C.  So my hybrid approach has been to write a
makefile for the C, and then make the haskell program depend on the .o
files and invoke ghc --make on them, like so:

_dummy_target: cfile.o
  ghc -Ic_includes -Lc_libs --make -main-is HsMain -o target HsMain.hs
cfile.o -lclib

Unfortunately, ghc doesn't seem relink the target if cfile.o changed,
so as a hack I put 'rm target' before the ghc line to make it link
every time.

Does anyone have a better solution?

#2 is structs.  What's a good way to marshal structs?  The
straightforward way would be C stubs like "T get_t(struct foo *x)" for
every field of the struct, but clearly at any kind of scale something
like greencard will be necessary (as an aside, greencard's last update
seems to have been "support this newfangled FFI"... is it still alive
and just "done" or are people using something else nowadays?).
Hopefully in can be made efficient though (I don't know if cross
C-haskell inlining will happen, but maybe with -fvia-c?).  The other
issue is that the haskell type will not be Storable, so the
Foreign.Array stuff won't work... I need a separate sizeof C stub and
allocaBytes.

It's much easier to declare e.g. "type SomeCStruct = Word64" and then
use Bits to pick out the fields in pure haskell, but I imagine this
assumes way too much about how the struct is layed out in memory.


More information about the Haskell-Cafe mailing list