X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fffi-chap.xml;h=96cbd596e518e83709a67c9c3bbf804f1b838086;hb=d62101efb9e263173b69fb89c07f03dcf805e81f;hp=78c23f8f9e0b1d420ba2f250804a5caefb091e40;hpb=284e6b500dd92bb132845c39ec1a9d8ef78c009a;p=ghc-hetmet.git
diff --git a/docs/users_guide/ffi-chap.xml b/docs/users_guide/ffi-chap.xml
index 78c23f8..96cbd59 100644
--- a/docs/users_guide/ffi-chap.xml
+++ b/docs/users_guide/ffi-chap.xml
@@ -10,37 +10,25 @@ Foreign function interface (FFI)
Addendum 1.0, whose definition is available from http://haskell.org/.
To enable FFI support in GHC, give the
- flag, or
+ flag, or
the flag which implies
.
- The FFI support in GHC diverges from the Addendum in the following ways:
-
-
-
- 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.
-
-
+ 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.
+ 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.
+ GHC. Your code will not be portable to other compilers if you use them.
Unboxed types
@@ -54,7 +42,7 @@ the
-
+ Newtype wrapping of the IO monadThe FFI spec requires the IO monad to appear in various places,
but it can sometimes be convenient to wrap the IO monad in a
@@ -78,10 +66,9 @@ OK:
-
-
+ Using the FFI with GHCThe following sections also give some hints and tips on the
@@ -137,6 +124,13 @@ extern HsInt foo(HsInt a0);
option; see .
+ 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 your own main()
@@ -188,10 +182,10 @@ int main(int argc, char *argv[])
The call to hs_init()
initializes GHC's runtime system. Do NOT try to invoke any
Haskell functions before calling
- hs_init(): strange things will
+ hs_init(): bad things will
undoubtedly happen.
- We pass argc and
+ We pass references to argc and
argv to hs_init()
so that it can separate out any arguments for the RTS
(i.e. those arguments between
@@ -214,13 +208,45 @@ int main(int argc, char *argv[])
M is
__stginit_M, and
it may be declared as an external function symbol as in the
- code above.
+ code above. Note that the symbol name should be transformed
+ according to the Z-encoding:
+
+
+
+
+
+ Character
+ Replacement
+
+
+
+
+ .
+ zd
+
+
+ _
+ zu
+
+
+ `
+ zq
+
+
+ Z
+ ZZ
+
+
+ z
+ zz
+
+
+
+ After we've finished invoking our Haskell functions, we
- can call hs_exit(), which
- terminates the RTS. It runs any outstanding finalizers and
- generates any profiling or stats output that might have been
- requested.
+ can call hs_exit(), which terminates the
+ RTS.
There can be multiple calls to
hs_init(), but each one should be matched
@@ -239,23 +265,87 @@ int main(int argc, char *argv[])
to the Main Haskell module.
-
- Using foreign import ccall "wrapper" with GHC
+
+ Making a Haskell library that can be called from foreign
+ code
- foreign import
- ccall "wrapper"with GHC
-
+ The scenario here is much like in , except that the aim is not to link a complete program, but to
+ make a library from Haskell code that can be deployed in the same
+ way that you would deploy a library of C code.
- When 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).
+ The main requirement here is that the runtime needs to be
+ initialized before any Haskell code can be called, so your library
+ should provide initialisation and deinitialisation entry points,
+ implemented in C or C++. For example:
+
+
+ HsBool mylib_init(void){
+ int argc = ...
+ char *argv[] = ...
+
+ // Initialize Haskell runtime
+ hs_init(&argc, &argv);
+
+ // Tell Haskell about all root modules
+ hs_add_root(__stginit_Foo);
+
+ // do any other initialization here and
+ // return false if there was a problem
+ return HS_BOOL_TRUE;
+ }
+
+ void mylib_end(void){
+ hs_exit();
+ }
+
+
+ The intialisation routine, mylib_init, calls
+ hs_init() and hs_add_root() as
+ normal to initialise the Haskell runtime, and the corresponding
+ deinitialisation funtion mylib_end() calls
+ hs_exit() to shut down the runtime.
+
+
+
+ On the use of hs_exit()
+
+ hs_exit() normally causes the termination of
+ any running Haskell threads in the system, and when
+ hs_exit() returns, there will be no more Haskell
+ threads running. The runtime will then shut down the system in an
+ orderly way, generating profiling
+ output and statistics if necessary, and freeing all the memory it
+ owns.
+
+ It isn't always possible to terminate a Haskell thread forcibly:
+ for example, the thread might be currently executing a foreign call,
+ and we have no way to force the foreign call to complete. What's
+ more, the runtime must
+ assume that in the worst case the Haskell code and runtime are about
+ to be removed from memory (e.g. if this is a Windows DLL,
+ hs_exit() is normally called before unloading the
+ DLL). So hs_exit()must wait
+ until all outstanding foreign calls return before it can return
+ itself.
+
+ The upshot of this is that if you have Haskell threads that are
+ blocked in foreign calls, then hs_exit() may hang
+ (or possibly busy-wait) until the calls return. Therefore it's a
+ good idea to make sure you don't have any such threads in the system
+ when calling hs_exit(). This includes any threads
+ doing I/O, because I/O may (or may not, depending on the
+ type of I/O and the platform) be implemented using blocking foreign
+ calls.
+
+ The GHC runtime treats program exit as a special case, to avoid
+ the need to wait for blocked threads when a standalone
+ executable exits. Since the program and all its threads are about to
+ terminate at the same time that the code is removed from memory, it
+ isn't necessary to ensure that the threads have exited first.
+ (Unofficially, if you want to use this fast and loose version of
+ hs_exit(), then call
+ shutdownHaskellAndExit() instead).
@@ -265,7 +355,7 @@ int main(int argc, char *argv[])
C calls, function headersWhen generating C (using the
- directive), one can assist the C compiler in detecting type
+ flag), one can assist the C compiler in detecting type
errors by using the directive
() to provide
.h files containing function
@@ -302,10 +392,10 @@ the module being compiled, you should supply all the options are; but they should be in the package
-configuration, which GHC knows about. So if you are building a package, remember
-to put all those options into the package configuration.
-See the c_includes field in .
-
+configuration, which GHC knows about. So if you are building a package using
+ Cabal, remember to put all those include files in the package
+ description (see the includes field in the Cabal
+ documentation).
It is also possible, according the FFI specification, to put the