Foreign function interfaceThe foreign interface consists of the following components:The Foreign Function Interface language specification
(which constitutes most of this Chapter, beginning with ). You must use the
command-line option to make GHC
understand the foreign declarations defined
by the FFI.The Foreign module (see ) collects together several interfaces
which are useful in specifying foreign language interfaces,
including the following:The ForeignObj module (see ), for managing pointers from
Haskell into the outside world.The StablePtr module (see ), for managing pointers into
Haskell from the outside world.The CTypes module (see ) gives Haskell equivalents for the
standard C datatypes, for use in making Haskell bindings to
existing C libraries.The CTypesISO module (see ) gives Haskell equivalents for C
types defined by the ISO C standard.The Storable library, for primitive
marshalling of data types between Haskell and the foreign
language.
&ffi-body;
Using the FFI with GHCThe following sections also give some hints and tips on the
use of the foreign function interface in GHC.Using foreign export dynamic with
GHCforeign export
dynamicwith GHCWhen GHC compiles a module (say M.hs)
which uses foreign export dynamic, it
generates two additional files, M_stub.c
and M_stub.h. GHC will automatically
compile M_stub.c to generate
M_stub.o at the same time.The C file M_stub.c contains small
helper functions used by the code generated for the
foreign export dynamic, so it must be linked
in to the final program. When linking the program, remember to
include M_stub.o in the final link command
line, or you'll get link errors for the missing function(s)
(this isn't necessary when building your program with
ghc --make, as GHC will automatically link in
the correct bits).Using function headersC calls, function headersWhen generating C (using the
directive), one can assist the C compiler in detecting type
errors by using the directive
() to provide
.h files containing function
headers.For example,
#include "HsFFI.h"
void initialiseEFS (HsInt size);
HsInt terminateEFS (void);
HsForeignObj emptyEFS(void);
HsForeignObj updateEFS (HsForeignObj a, HsInt i, HsInt x);
HsInt lookupEFS (HsForeignObj a, HsInt i);
The types HsInt,
HsForeignObj etc. are described in .Note that this approach is only
essential for returning
floats (or if sizeof(int) !=
sizeof(int *) on your architecture) but is a Good
Thing for anyone who cares about writing solid code. You're
crazy not to do it.