X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fffi-chap.xml;h=49896b92e0549c6d224425d9986302fe4343f9c5;hb=836cafeb3edd9c728fe4c86cf90229e1476ad14a;hp=8928ea8a7f7d5debab0f7f3b1bdc0c28b02b9ebf;hpb=a8e681c1e8aa4bc602714ff61583cd4e969d7187;p=ghc-hetmet.git diff --git a/docs/users_guide/ffi-chap.xml b/docs/users_guide/ffi-chap.xml index 8928ea8..49896b9 100644 --- a/docs/users_guide/ffi-chap.xml +++ b/docs/users_guide/ffi-chap.xml @@ -7,40 +7,28 @@ 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/. + Addendum 1.0, whose definition is available from http://www.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 Addendum The 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 @@ -67,7 +55,7 @@ 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 <literal>main()</literal> @@ -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 <literal>foreign import ccall "wrapper"</literal> 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 initialisation routine, mylib_init, calls + hs_init() and hs_add_root() as + normal to initialise the Haskell runtime, and the corresponding + deinitialisation function mylib_end() calls + hs_exit() to shut down the runtime. + + + + On the use of <literal>hs_exit()</literal> + + 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 headers When 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