From 0346ecd9a5f920e21d177df7fc26b53f01f14122 Mon Sep 17 00:00:00 2001 From: simonmar Date: Fri, 14 Sep 2001 15:56:40 +0000 Subject: [PATCH] [project @ 2001-09-14 15:56:40 by simonmar] Document how to use "foreign export" with GHC, including how to call startupHaskell()/shutdownHaskell() when providing your own main(). --- ghc/docs/users_guide/ffi-chap.sgml | 153 +++++++++++++++++++++++++++++++----- 1 file changed, 135 insertions(+), 18 deletions(-) diff --git a/ghc/docs/users_guide/ffi-chap.sgml b/ghc/docs/users_guide/ffi-chap.sgml index 1bcc717..d0f6878 100644 --- a/ghc/docs/users_guide/ffi-chap.sgml +++ b/ghc/docs/users_guide/ffi-chap.sgml @@ -65,32 +65,149 @@ The following sections also give some hints and tips on the use of the foreign function interface in GHC. - - Using <literal>foreign export dynamic</literal> with - GHC + + Using <literal>foreign export</literal> with GHC foreign export - dynamicwith GHC + with GHC When 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 + which uses foreign export or 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). - + 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 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 <literal>main()</literal> + + 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. + + + + Using <literal>foreign export dynamic</literal> with + GHC + + foreign export + dynamicwith GHC + + + When foreign export dynamic 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 + 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 headers -- 1.7.10.4