Commit 94fb7e72 authored by simonmar's avatar simonmar
Browse files

[project @ 2003-01-28 16:57:40 by simonmar]

Update the FFI docs to use hs_init()/hs_exit() rather than
startupHaskell()/shutdownHaskell().
parent 34b568ce
...@@ -132,64 +132,83 @@ extern HsInt foo(HsInt a0);</programlisting> ...@@ -132,64 +132,83 @@ extern HsInt foo(HsInt a0);</programlisting>
<programlisting> <programlisting>
#include &lt;stdio.h&gt; #include &lt;stdio.h&gt;
#include "foo_stub.h" #include "HsFFI.h"
#include "RtsAPI.h" #ifdef __GLASGOW_HASKELL__
#include "foo_stub.h"
#endif
#ifdef __GLASGOW_HASKELL__
extern void __stginit_Foo ( void ); extern void __stginit_Foo ( void );
#endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i; int i;
startupHaskell(argc, argv, __stginit_Foo); hs_init(&amp;argc, &amp;argv);
#ifdef __GLASGOW_HASKELL__
hs_add_root(__stginit_Foo);
#endif
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
printf("%d\n", foo(2500)); printf("%d\n", foo(2500));
} }
shutdownHaskell(); hs_exit();
return 0; return 0;
}</programlisting> }</programlisting>
<para>The call to <literal>startupHaskell()</literal> <para>We've surrounded the GHC-specific bits with
<literal>#ifdef __GLASGOW_HASKELL__</literal>; the rest of the
code should be portable across Haskell implementations that
support the FFI standard.</para>
<para>The call to <literal>hs_init()</literal>
initializes GHC's runtime system. Do NOT try to invoke any initializes GHC's runtime system. Do NOT try to invoke any
Haskell functions before calling Haskell functions before calling
<literal>startupHaskell()</literal>: strange things will <literal>hs_init()</literal>: strange things will
undoubtedly happen.</para> undoubtedly happen.</para>
<para>We pass <literal>argc</literal> and <para>We pass <literal>argc</literal> and
<literal>argv</literal> to <literal>startupHaskell()</literal> <literal>argv</literal> to <literal>hs_init()</literal>
so that it can separate out any arguments for the RTS so that it can separate out any arguments for the RTS
(i.e. those arguments between (i.e. those arguments between
<literal>+RTS...-RTS</literal>).</para> <literal>+RTS...-RTS</literal>).</para>
<para>The third argument to <literal>startupHaskell()</literal> <para>Next, we call
is used for initializing the Haskell modules in the program. <function>hs_add_root</function><indexterm><primary><function>hs_add_root</function></primary>
It must be the name of the initialization function for the </indexterm>, a GHC-specific interface which is required to
"top" module in the program/library - in other words, the initialise the Haskell modules in the program. The argument
module which directly or indirectly imports all the other to <function>hs_add_root</function> should be the name of the
Haskell modules in the program. In a standalone Haskell initialization function for the "root" module in your program
program this would be module <literal>Main</literal>, but when - in other words, the module which directly or indirectly
you are only using the Haskell code as a library it may not imports all the other Haskell modules in the program. In a
be. If your library doesn't have such a module, then it is standalone Haskell program the root module is normally
straightforward to create one, purely for this initialization <literal>Main</literal>, but when you are using Haskell code
process. The name of the initialization function for module from a library it may not be. If your program has multiple
root modules, then you can call
<function>hs_add_root</function> multiple times, one for each
root. The name of the initialization function for module
<replaceable>M</replaceable> is <replaceable>M</replaceable> is
<literal>__stginit_<replaceable>M</replaceable></literal>, and <literal>__stginit_<replaceable>M</replaceable></literal>, and
it may be declared as an external function symbol as in the it may be declared as an external function symbol as in the
code above.</para> code above.</para>
<para>After we've finished invoking our Haskell functions, we <para>After we've finished invoking our Haskell functions, we
can call <literal>shutdownHaskell()</literal>, which can call <literal>hs_exit()</literal>, which
terminates the RTS. It runs any outstanding finalizers and terminates the RTS. It runs any outstanding finalizers and
generates any profiling or stats output that might have been generates any profiling or stats output that might have been
requested.</para> requested.</para>
<para>The functions <literal>startupHaskell()</literal> and <para>There can be multiple calls to
<literal>shutdownHaskell()</literal> may be called only once <literal>hs_init()</literal>, but each one should be matched
each, and only in that order.</para> by one (and only one) call to
<literal>hs_exit()</literal><footnote><para>The outermost
<literal>hs_exit()</literal> will actually de-initialise the
system. NOTE that currently GHC's runtime cannot reliably
re-initialise after this has happened.</para>
</footnote>.</para>
<para>NOTE: when linking the final program, it is normally <para>NOTE: when linking the final program, it is normally
easiest to do the link using GHC, although this isn't easiest to do the link using GHC, although this isn't
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment