Foreign function interface (FFI)GHC (mostly) conforms to the Haskell 98 Foreign Function Interface
Addendum 1.0, whose definition is available from http://haskell.org/.
The FFI support in GHC diverges from the Addendum in the following ways:
The routines hs_init(),
hs_exit(), and hs_set_argv() from
Chapter 6.1 of the Addendum are not supported yet.Syntactic forms and library functions proposed in earlier versions
of the FFI are still supported for backwards compatibility.GHC implements a number of GHC-specific extensions to the FFI
Addendum. These extensions are described in , but please note that programs using
these features are not portable. Hence, these features should be
avoided where possible.The FFI libraries are documented in the accompanying library
documentation; see for example the Foreign
module.GHC extensions to the FFI AddendumThe FFI features that are described in this section are specific to
GHC. Avoid them where possible to not compromise the portability of the
resulting code.ArraysThe types ByteArray and
MutableByteArray may be used as basic foreign types
(see FFI Addendum, Section 3.2). In C land, they map to
(char *).Unboxed typesThe following unboxed types may be used as basic foreign types
(see FFI Addendum, Section 3.2): Int#,
Word#, Char#,
Float#, Double#,
Addr#, StablePtr# a,
MutableByteArray#, ForeignObj#,
and ByteArray#.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 and foreign
import ccall "wrapper" with GHCforeign export
with GHCWhen GHC compiles a module (say M.hs)
which uses foreign export or foreign
import "wrapper", 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.For a plain foreign export, the file
M_stub.h contains a C prototype for the
foreign exported function, and M_stub.c
contains its definition. For example, if we compile the
following module:
module Foo where
foreign export ccall foo :: Int -> IO Int
foo :: Int -> IO Int
foo n = return (length (f n))
f :: Int -> [Int]
f 0 = []
f n = n:(f (n-1))Then Foo_stub.h will contain
something like this:
#include "HsFFI.h"
extern HsInt foo(HsInt a0);and Foo_stub.c contains the
compiler-generated definition of foo(). To
invoke foo() from C, just #include
"Foo_stub.h" and call foo().Using your own main()Normally, GHC's runtime system provides a
main(), which arranges to invoke
Main.main in the Haskell program. However,
you might want to link some Haskell code into a program which
has a main function written in another languagem, say C. In
order to do this, you have to initialize the Haskell runtime
system explicitly.Let's take the example from above, and invoke it from a
standalone C program. Here's the C code:
#include <stdio.h>
#include "foo_stub.h"
#include "RtsAPI.h"
extern void __stginit_Foo ( void );
int main(int argc, char *argv[])
{
int i;
startupHaskell(argc, argv, __stginit_Foo);
for (i = 0; i < 5; i++) {
printf("%d\n", foo(2500));
}
shutdownHaskell();
return 0;
}The call to startupHaskell()
initializes GHC's runtime system. Do NOT try to invoke any
Haskell functions before calling
startupHaskell(): strange things will
undoubtedly happen.We pass argc and
argv to startupHaskell()
so that it can separate out any arguments for the RTS
(i.e. those arguments between
+RTS...-RTS).The third argument to startupHaskell()
is used for initializing the Haskell modules in the program.
It must be the name of the initialization function for the
"top" module in the program/library - in other words, the
module which directly or indirectly imports all the other
Haskell modules in the program. In a standalone Haskell
program this would be module Main, but when
you are only using the Haskell code as a library it may not
be. If your library doesn't have such a module, then it is
straightforward to create one, purely for this initialization
process. The name of the initialization function for module
M is
__stginit_M, and
it may be declared as an external function symbol as in the
code above.After we've finished invoking our Haskell functions, we
can call shutdownHaskell(), which
terminates the RTS. It runs any outstanding finalizers and
generates any profiling or stats output that might have been
requested.The functions startupHaskell() and
shutdownHaskell() may be called only once
each, and only in that order.NOTE: when linking the final program, it is normally
easiest to do the link using GHC, although this isn't
essential. If you do use GHC, then don't forget the flag
, otherwise GHC will try to link
to the Main Haskell module.Using foreign import ccall "wrapper" with
GHCforeign import
ccall "wrapper"with GHCWhen foreign import ccall "wrapper" is used
in a Haskell module, The C stub file M_stub.c
generated by GHC contains small helper functions used by the code
generated for the imported wrapper, 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 the H98 FFI
Addendum.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.