-<Sect1 id="sec-intro">
+<Sect1 id="sec-ffi-intro">
<Title>Introduction
</Title>
<Para>
-The motivation behind this foreign function interface(FFI)
-specification is to make it possible to describe in Haskell <Emphasis>source
-code</Emphasis> the interface to foreign functionality in a Haskell system
-independent manner. It builds on experiences made with the previous
-foreign function interfaces provided by GHC and Hugs.
+The motivation behind this foreign function interface (FFI) specification is
+to make it possible to describe in Haskell <Emphasis>source code</Emphasis>
+the interface to foreign functionality in a Haskell system independent
+manner. It builds on experiences made with the previous foreign function
+interfaces provided by GHC and Hugs. However, the FFI specified in this
+document is not in the market of trying to completely bridge the gap between
+the actual type of an external function, and what is a
+<Emphasis>convenient</Emphasis> type for that function to the Haskell
+programmer. That is the domain of tools like HaskellDirect or Green Card, both
+of which are capable of generating Haskell code that uses this FFI.
</Para>
<Para>
-The FFI specified in this document is not in the market of trying to
-completely bridge the gap between the actual type of an external
-function, and what is a <Emphasis>convenient</Emphasis> type for that function to the
-Haskell programmer. That is the domain of tools like HaskellDirect or
-Green Card, both of which are capable of generating Haskell code that
-uses this FFI.
+Generally, the FFI consists of three parts:
+<OrderedList>
+
+<ListItem>
+<Para>
+extensions to the base language Haskell 98 (most notably <Literal>foreign
+import</Literal> and <Literal>foreign export</Literal> declarations), which
+are specified in the present document,
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+a low-level marshalling library, which is part of the
+<Emphasis>Language</Emphasis> part of the <Emphasis>Haskell Extension
+Library</Emphasis> (see <xref linkend="sec-Storable">), and a
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+a high-level marshalling library, which is still under development.
+</Para>
+</ListItem>
+
+</OrderedList>
+Before diving into the details of the language extension coming with the FFI,
+let us briefly outline the two other components of the interface.
+</Para>
+
+<Para>
+The low-level marshalling library consists of a portion that is independent of
+the targeted foreign language and dedicated support for Haskell bindings to C
+libraries (special support for other languages may be added in the future).
+The language independent part is given by the module
+<literal>Foreign</literal> module (see <xref linkend="sec-Foreign">). It
+provides support for handling references to foreign structures, for passing
+references to Haskell structures out to foreign routines, and for storing
+primitive data types in raw memory blocks in a portable manner. The support
+for C libraries essentially provides Haskell representations for all basic
+types of C (see <xref linkend="sec-CTypes"> and <xref
+linkend="sec-CTypesISO">).
</Para>
<Para>
-The FFI can be split up into two complementary halves; one half that
-provides Haskell constructs for importing foreign functionality into
-Haskell, the other which lets you expose Haskell functions to the
-outside world. We start with the former, how to import external
-functionality into Haskell.
+The high-level library, of which the interface definition is not yet
+finalised, provides routines for marshalling complex Haskell structures as
+well as handling out and in-out parameters in a convenient, yet protable way.
+</Para>
+
+<Para>
+In the following, we will discuss the language extensions of the FFI (i.e. the
+first point above). They can be split up into two complementary halves; one
+half that provides Haskell constructs for importing foreign functionality into
+Haskell, the other which lets you expose Haskell functions to the outside
+world. We start with the former, how to import external functionality into
+Haskell.
</Para>
</Sect1>
-<Sect1 id="sec-primitive">
+<Sect1 id="sec-ffi-primitive">
<Title>Calling foreign functions
</Title>
an unsafe thing to do, as the external name will in most cases be
untyped. The onus is on the programmer using <Literal>foreign import</Literal> to
ensure that the Haskell type given correctly maps on to the
-type of the external function. Section
-<XRef LinkEnd="sec-mapping"> specifies the mapping from
+type of the external function.
+<XRef LinkEnd="sec-ffi-mapping"> specifies the mapping from
Haskell types to external types.
</Para>
-<Sect2 id="sec-prim-name">
+<Sect2 id="sec-ffi-prim-name">
<Title>Giving the external function a Haskell name
</Title>
</Sect2>
-<Sect2 id="sec-prim-ext-name">
+<Sect2 id="sec-ffi-prim-ext-name">
<Title>Naming the external function
</Title>
</Sect2>
-<Sect2 id="sec-cconv">
+<Sect2 id="sec-ffi-cconv">
<Title>Calling conventions
</Title>
<Footnote>
<Para>
-The <Literal>stdcall</Literal> is a Microsoft Win32 specific wrinkle; it used
+The <Literal>stdcall</Literal> is a Microsoft Win32 specific wrinkle; it's used
throughout the Win32 API, for instance. On platforms where
<Literal>stdcall</Literal> isn't meaningful, it should be treated as being equal
to <Literal>ccall</Literal>.
</Sect2>
-<Sect2 id="sec-prim-types">
+<Sect2 id="sec-ffi-prim-types">
<Title>External function types
</Title>
GHC permits the passing of its byte array primitive types
to external functions. There's some restrictions on when
-they can be used; see Section <XRef LinkEnd="sec-arguments">
+they can be used; see <XRef LinkEnd="sec-ffi-arguments">
for more details.
</Para>
</ListItem>
</Para>
<Para>
-Section <XRef LinkEnd="sec-results"> defines
-<Literal>prim_result</Literal>; Section <XRef LinkEnd="sec-arguments">
+<XRef LinkEnd="sec-ffi-results"> defines
+<Literal>prim_result</Literal>; <XRef LinkEnd="sec-ffi-arguments">
defines <Literal>prim_arg</Literal>.
</Para>
-<Sect3 id="sec-arguments">
+<Sect3 id="sec-ffi-arguments">
<Title>Argument types
</Title>
The <Emphasis>stable pointer</Emphasis> <Literal>StablePtr</Literal> type looks out of place in
this list of C-like types, but it has a well-defined and simple
-C mapping, see Section <XRef LinkEnd="sec-mapping">
+C mapping, see <XRef LinkEnd="sec-ffi-mapping">
for details.
</Para>
</Sect3>
-<Sect3 id="sec-results">
+<Sect3 id="sec-ffi-results">
<Title>Result type
</Title>
</Sect2>
-<Sect2 id="sec-mapping">
+<Sect2 id="sec-ffi-mapping">
<Title>Type mapping
</Title>
and the outside, needs to be precisely defined. We do this by
presenting a mapping to C, as it is commonly used and most other
languages define a mapping to it. Table
-<XRef LinkEnd="sec-mapping-table">
+<XRef LinkEnd="sec-ffi-mapping-table">
defines the mapping between Haskell and C types.
</Para>
<Para>
-<Table id="sec-mapping-table">
+<Table id="sec-ffi-mapping-table">
<Title>Mapping of Haskell types to C types</Title>
-<TGroup Cols="6">
-<ColSpec Align="Left" Colsep="0">
-<ColSpec Align="Left" Colsep="0">
+<TGroup Cols="4">
<ColSpec Align="Left" Colsep="0">
<ColSpec Align="Left" Colsep="0">
<ColSpec Align="Left" Colsep="0">
<Literal>Char</Literal> </Entry>
<Entry> <Literal>HsChar</Literal> </Entry>
<Entry> unspec. integral type </Entry>
-<Entry> <Literal>HS_CHAR_MIN</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_CHAR_MAX</Literal></Entry>
+<Entry> <Literal>HS_CHAR_MIN</Literal> .. <Literal>HS_CHAR_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Literal>Int</Literal> </Entry>
<Entry> <Literal>HsInt</Literal> </Entry>
<Entry> signed integral of unspec. size(4) </Entry>
-<Entry> <Literal>HS_INT_MIN</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_INT_MAX</Literal></Entry>
+<Entry> <Literal>HS_INT_MIN</Literal> ..
+<Literal>HS_INT_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Literal>Int8</Literal> (2) </Entry>
<Entry> <Literal>HsInt8</Literal> </Entry>
<Entry> 8 bit signed integral </Entry>
-<Entry> <Literal>HS_INT8_MIN</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_INT8_MAX</Literal></Entry>
+<Entry> <Literal>HS_INT8_MIN</Literal>
+..
+<Literal>HS_INT8_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Literal>Int16</Literal> (2) </Entry>
<Entry> <Literal>HsInt16</Literal> </Entry>
<Entry> 16 bit signed integral </Entry>
-<Entry> <Literal>HS_INT16_MIN</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_INT16_MAX</Literal></Entry>
+<Entry> <Literal>HS_INT16_MIN</Literal>
+.. <Literal>HS_INT16_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Literal>Int32</Literal> (2) </Entry>
<Entry> <Literal>HsInt32</Literal> </Entry>
<Entry> 32 bit signed integral </Entry>
-<Entry> <Literal>HS_INT32_MIN</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_INT32_MAX</Literal></Entry>
+<Entry> <Literal>HS_INT32_MIN</Literal> ..
+<Literal>HS_INT32_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Literal>Int64</Literal> (2,3) </Entry>
<Entry> <Literal>HsInt64</Literal> </Entry>
<Entry> 64 bit signed integral (3) </Entry>
-<Entry> <Literal>HS_INT64_MIN</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_INT64_MAX</Literal></Entry>
+<Entry> <Literal>HS_INT64_MIN</Literal> ..
+<Literal>HS_INT64_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Literal>Word8</Literal> (2) </Entry>
<Entry> <Literal>HsWord8</Literal> </Entry>
<Entry> 8 bit unsigned integral </Entry>
-<Entry> <Literal>0</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_WORD8_MAX</Literal></Entry>
+<Entry> <Literal>0</Literal> ..
+<Literal>HS_WORD8_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Literal>Word16</Literal> (2) </Entry>
<Entry> <Literal>HsWord16</Literal> </Entry>
<Entry> 16 bit unsigned integral </Entry>
-<Entry> <Literal>0</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_WORD16_MAX</Literal></Entry>
+<Entry> <Literal>0</Literal> ..
+<Literal>HS_WORD16_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Literal>Word32</Literal> (2) </Entry>
<Entry> <Literal>HsWord32</Literal> </Entry>
<Entry> 32 bit unsigned integral </Entry>
-<Entry> <Literal>0</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_WORD32_MAX</Literal></Entry>
+<Entry> <Literal>0</Literal> ..
+<Literal>HS_WORD32_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Literal>Word64</Literal> (2,3) </Entry>
<Entry> <Literal>HsWord64</Literal> </Entry>
<Entry> 64 bit unsigned integral (3) </Entry>
-<Entry> <Literal>0</Literal> </Entry>
-<Entry>..</Entry>
-<Entry> <Literal>HS_WORD64_MAX</Literal></Entry>
+<Entry> <Literal>0</Literal> ..
+<Literal>HS_WORD64_MAX</Literal></Entry>
</Row>
<Row>
<Entry>
<Entry> <Literal>HsFloat</Literal> </Entry>
<Entry> floating point of unspec. size (5) </Entry>
<Entry> (10) </Entry>
-<Entry> </Entry>
-<Entry> </Entry>
</Row>
<Row>
<Entry>
<Entry> <Literal>HsDouble</Literal> </Entry>
<Entry> floating point of unspec. size (5) </Entry>
<Entry> (10) </Entry>
-<Entry> </Entry>
-<Entry> </Entry>
</Row>
<Row>
<Entry>
<Entry> <Literal>HsBool</Literal> </Entry>
<Entry> unspec. integral type </Entry>
<Entry> (11) </Entry>
-<Entry> </Entry>
-<Entry> </Entry>
</Row>
<Row>
<Entry>
<Entry> <Literal>HsAddr</Literal> </Entry>
<Entry> void* (6) </Entry>
<Entry> </Entry>
-<Entry> </Entry>
-<Entry> </Entry>
</Row>
<Row>
<Entry>
<Entry> <Literal>HsForeignObj</Literal> </Entry>
<Entry> void* (7) </Entry>
<Entry> </Entry>
-<Entry> </Entry>
-<Entry> </Entry>
</Row>
<Row>
<Entry>
<Entry> <Literal>HsStablePtr</Literal> </Entry>
<Entry> void* (8) </Entry>
<Entry> </Entry>
-<Entry> </Entry>
-<Entry> </Entry>
-</Row>
-<Row>
-<Entry>
-</Entry>
</Row>
</TBody>
</Sect2>
-<Sect2 id="sec-prim-remarks">
+<Sect2 id="sec-ffi-prim-remarks">
<Title>Some <Literal>foreign import</Literal> wrinkles
</Title>
of being called. This will typically happen when the imported
function end up calling Haskell functions that reside in the same
'Haskell world' (i.e., shares the same storage manager heap) -- see
-Section <XRef LinkEnd="sec-entry"> for
+<XRef LinkEnd="sec-ffi-entry"> for
details of how the FFI let's you call Haskell functions from the outside.
If the programmer can guarantee that the imported function won't
call back into Haskell, the <Literal>foreign import</Literal> can be marked as
-'unsafe' (see Section <XRef LinkEnd="sec-primitive"> for details of
+'unsafe' (see <XRef LinkEnd="sec-ffi-primitive"> for details of
how to do this.)
Unsafe calls are cheaper than safe ones, so distinguishing the two
f :: Addr -> IO ()
f ptr = do
- fo <- makeForeignObj ptr myFinalizer
+ fo <- newForeignObj ptr myFinalizer
mumble fo
</ProgramListing>
</Sect1>
-<Sect1 id="sec-prim-dynamic">
+<Sect1 id="sec-ffi-prim-dynamic">
<Title>Invoking external functions via a pointer
</Title>
</Sect1>
-<Sect1 id="sec-entry">
+<Sect1 id="sec-ffi-entry">
<Title>Exposing Haskell functions
</Title>
</Para>
-<Sect2 id="sec-callback">
+<Sect2 id="sec-ffi-callback">
<Title>Exposing Haskell function values
</Title>
<Para>
where <Literal>cType[[]]</Literal> is the Haskell to C type mapping presented
-in Section <XRef LinkEnd="sec-mapping">.
+in <XRef LinkEnd="sec-ffi-mapping">.
</Para>
<Para>
</Sect2>
-<Sect2 id="sec-foreign-label">
+<Sect2 id="sec-ffi-foreign-label">
<Title>Code addresses
</Title>
</Sect2>
</Sect1>
-
-<Sect1 id="sec-changelog">
+<!-- This doesn't need to be seen in the docs
+<Sect1 id="sec-ffi-changelog">
<Title>Change history
</Title>
<ListItem>
<Para>
-0.95 --> 0.96:
+0.95 > 0.96:
<ItemizedList>
<ListItem>
<Para>
changed the C representation of <Literal>Haskell_ForeignObj</Literal> from
-<Literal>(long*)</Literal> to <Literal>(void*)</Literal> -- ANSI C guarantees that <Literal>(void*)</Literal>
+<Literal>(long*)</Literal> to <Literal>(void*)</Literal> ANSI C guarantees that <Literal>(void*)</Literal>
is the widest possible data pointer.
</Para>
</ListItem>
<ListItem>
<Para>
-Updated defnition of <Literal>varid</Literal> in Section
-<XRef LinkEnd="sec-prim-name"> to reflect Haskell98's.
+Updated defnition of <Literal>varid</Literal> in
+<XRef LinkEnd="sec-ffi-prim-name"> to reflect Haskell98's.
</Para>
</ListItem>
<ListItem>
<ListItem>
<Para>
-0.96 --> 0.97:
+0.96 > 0.97:
<ItemizedList>
<ListItem>
<ListItem>
<Para>
-0.97 --> 0.98:
+0.97 > 0.98:
<ItemizedList>
<ListItem>
<ListItem>
<Para>
-0.98 --> 0.99:
+0.98 > 0.99:
<ItemizedList>
<ListItem>
<ListItem>
<Para>
-0.99 --> 0.99.1:
+0.99 > 0.99.1:
<ItemizedList>
<ListItem>
</Para>
</Sect1>
+-->