-<Sect1 id="sec-intro">
+<Sect1 id="sec-ffi-intro">
<Title>Introduction
</Title>
</Para>
<Para>
-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-???">), 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 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 (ie, 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.
+In the following, we will discuss the language extensions of the FFI.
+The extensions 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>
<Para>
-The name of the external function consists of two parts,
-one specifying its location, the other its name:
+The name of the external function is a string:
</Para>
-<Para>
-
<ProgramListing>
-ext_fun : ext_loc ext_name
- | ext_name
-
-ext_name : string
-ext_loc : string
-</ProgramListing>
-
-</Para>
+ext_fun : string</ProgramListing>
<Para>
For example,
</Para>
-<Para>
-
<ProgramListing>
-foreign import stdcall "Advapi32" "RegCloseKey" regCloseKey :: Addr -> IO ()
+foreign import stdcall "RegCloseKey" regCloseKey :: Ptr a -> IO ()
</ProgramListing>
-</Para>
-
<Para>
-states that the external function named <Function>RegCloseKey</Function> at location
-<Function>Advapi32</Function> should be bound to the Haskell name <Function>regCloseKey</Function>.
-For a Win32 Haskell implementation that supports the loading of DLLs
-on-the-fly, this declaration will most likely cause the run-time
-system to load the <Filename>Advapi32.dll</Filename> DLL before looking up the
-function <Function>RegCloseKey()</Function> therein to get at the function pointer
-to use when invoking <Function>regCloseKey</Function>.
-</Para>
+states that the external function named <Function>RegCloseKey</Function> should be bound to the Haskell name <Function>regCloseKey</Function>.</Para>
<Para>
-Compiled implementations may do something completely different, i.e.,
-mangle "RegCloseKey" to convert it into an archive/import library
-symbol, that's assumed to be in scope when linking. The details of
-which are platform (and compiler command-line) dependent.
-</Para>
+The details of where exactly the external name can be found, such as
+whether or not it is dynamically linked, and which library it might
+come from, are implementation dependent. This information is expected
+to be provided using a compiler-specific method (eg. GHC uses either
+packages or command-line options to specify libraries and extra
+include files).</para>
<Para>
-If the location part is left out, the name of the external function
-specifies a symbol that is assumed to be in scope when linking.
-</Para>
-
-<Para>
-The location part can either contain an absolute `address' (i.e.,
-path) of the archive/DLL, or just its name, leaving it up to the
-underlying system (system meaning both RTS/compiler and OS) to resolve
-the name to its real location.
-</Para>
-
-<Para>
-An implementation is <Emphasis>expected</Emphasis> to be able to intelligently
-transform the <Literal>ext_loc</Literal> location to fit platform-specific
-practices for naming dynamic libraries. For instance, given the
-declaration
+If the Haskell name of the imported function is identical to the
+external name, the <Literal>ext_fun</Literal> can be
+omitted. e.g.:
</Para>
<Para>
<ProgramListing>
-foreign import "Foo" "foo" foo :: Int -> Int -> IO ()
-</ProgramListing>
-
-</Para>
-
-<Para>
-an implementation should map <Filename>Foo</Filename> to <Filename>"Foo.dll"</Filename> on a Win32
-platform, and <Filename>libFoo.so</Filename> on ELF platforms. If the lookup of the
-dynamic library with this transformed location name should fail, the
-implementation should then attempt to use the original name before
-eventually giving up. As part of their documentation, implementations
-of <Literal>foreign import</Literal> should specify the exact details of how
-<Literal>ext_loc</Literal>s are transformed and resolved, including the list of
-directories searched (and the order in which they are.)
-</Para>
-
-<Para>
-In the case the Haskell name of the imported function is identical to
-the external name, the <Literal>ext_fun</Literal> can be omitted. i.e.,
-</Para>
-
-<Para>
-
-<ProgramListing>
-foreign import sin :: Double -> IO Double
+foreign import sin :: Double -> IO Double
</ProgramListing>
</Para>
<Para>
<ProgramListing>
-foreign import "sin" sin :: Double -> IO Double
+foreign import "sin" sin :: Double -> IO Double
</ProgramListing>
</Para>
</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>
<ProgramListing>
prim_type : IO prim_result
| prim_result
- | prim_arg '->' prim_type
+ | prim_arg '->' prim_type
</ProgramListing>
</Para>
The external function is strict in all its arguments.
</Para>
</ListItem>
-<ListItem>
-
-<Para>
-<Emphasis>GHC only:</Emphasis> The GHC FFI implementation provides one extension
-to <Literal>prim_type</Literal>:
-
-
-<ProgramListing>
-prim_type : ...
- | unsafe_arr_ty '->' prim_type
-
-unsafe_arr_ty : ByteArray a
- | MutableByteArray i s a
-</ProgramListing>
-
-
-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">
-for more details.
-</Para>
-</ListItem>
</ItemizedList>
</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>
<Para>
<ProgramListing>
-prim_arg : ext_ty | new_ty | ForeignObj
+prim_arg : ext_ty | new_ty | ForeignPtr a
new_ty : a Haskell newtype of a prim_arg.
ext_ty : int_ty | word_ty | float_ty
- | Addr | Char | StablePtr a
+ | Ptr a | Char | StablePtr a
| Bool
int_ty : Int | Int8 | Int16 | Int32 | Int64
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>
<ListItem>
<Para>
-<Literal>prim_arg</Literal> represent the set of permissible argument types. In
-addition to <Literal>ext_ty</Literal>, <Literal>ForeignObj</Literal> is also included.
+<Literal>prim_arg</Literal> represent the set of permissible
+argument types. In addition to <Literal>ext_ty</Literal>,
+<Literal>ForeignPtr</Literal> is also included.
-The <Literal>ForeignObj</Literal> type represent values that are pointers to some
-external entity/object. It differs from the <Literal>Addr</Literal> type in that
-<Literal>ForeignObj</Literal>s are <Emphasis>finalized</Emphasis>, i.e., once the garbage collector
-determines that a <Literal>ForeignObj</Literal> is unreachable, it will invoke a
-finalising procedure attached to the <Literal>ForeignObj</Literal> to notify the
-outside world that we're through with using it.
+The <Literal>ForeignPtr</Literal> type represent values that are
+pointers to some external entity/object. It differs from the
+<Literal>Ptr</Literal> type in that <Literal>ForeignPtr</Literal>s are
+<Emphasis>finalized</Emphasis>, i.e., once the garbage collector
+determines that a <Literal>ForeignPtr</Literal> is unreachable, it
+will invoke a finalising procedure attached to the
+<Literal>ForeignPtr</Literal> to notify the outside world that we're
+through with using it.
</Para>
</ListItem>
<ListItem>
<Para>
-Haskell <Literal>newtype</Literal>s that wrap up a <Literal>prim_arg</Literal> type can also
-be passed to external functions.
+Haskell <Literal>newtype</Literal>s that wrap up a
+<Literal>prim_arg</Literal> type can also be passed to external
+functions.
</Para>
</ListItem>
<ListItem>
arguments represent a binding to a function with no arguments.
</Para>
</ListItem>
-<ListItem>
-
-<Para>
-<Emphasis>GHC only:</Emphasis> GHC's implementation of the FFI provides
-two extensions:
-<ItemizedList>
<ListItem>
-
<Para>
-Support for passing heap allocated byte arrays to an external
-function
-
-<ProgramListing>
-prim_type : ...
- | prim_arg '->' prim_type
- | unsafe_arr_ty '->' prim_type
-
-unsafe_arr_ty : ByteArray a
- | MutableByteArray i s a
-</ProgramListing>
-
-
-GHC's <Literal>ByteArray</Literal> and <Literal>MutableByteArray</Literal> primitive types are
-(im)mutable chunks of memory allocated on the Haskell heap, and
-pointers to these can be passed to <Literal>foreign import</Literal>ed external
-functions provided they are marked as <Literal>unsafe</Literal>. Since it is
-inherently unsafe to hand out references to objects in the Haskell
-heap if the external call may cause a garbage collection to happen,
-you have to annotate the <Literal>foreign import</Literal> declaration with
-the attribute <Literal>unsafe</Literal>. By doing so, the user explicitly states
-that the external function won't provoke a garbage collection,
-so passing out heap references to the external function is allright.
-
-</Para>
-</ListItem>
-<ListItem>
-
-<Para>
-Another GHC extension is the support for unboxed types:
+A GHC extension is the support for unboxed types:
<ProgramListing>
</ItemizedList>
</Para>
-</ListItem>
-
-</ItemizedList>
-
-</Para>
</Sect3>
-<Sect3 id="sec-results">
+<Sect3 id="sec-ffi-results">
<Title>Result type
</Title>
<ListItem>
<Para>
-Only external types (<Literal>ext_ty</Literal>) can be passed back, i.e., returning
-<Literal>ForeignObj</Literal>s is not supported/allowed.
+Only external types (<Literal>ext_ty</Literal>) can be passed
+back, i.e., returning <Literal>ForeignPtr</Literal>s is not
+supported/allowed.
</Para>
</ListItem>
<ListItem>
</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="4">
</Row>
<Row>
<Entry>
-<Literal>Addr</Literal> </Entry>
-<Entry> <Literal>HsAddr</Literal> </Entry>
+<Literal>Ptr a</Literal> </Entry>
+<Entry> <Literal>HsPtr</Literal> </Entry>
<Entry> void* (6) </Entry>
<Entry> </Entry>
</Row>
<Row>
<Entry>
-<Literal>ForeignObj</Literal> </Entry>
-<Entry> <Literal>HsForeignObj</Literal> </Entry>
+<Literal>ForeignPtr a</Literal> </Entry>
+<Entry> <Literal>HsForeignPtr</Literal> </Entry>
<Entry> void* (7) </Entry>
<Entry> </Entry>
</Row>
<Row>
<Entry>
-<Literal>StablePtr</Literal> </Entry>
+<Literal>StablePtr a</Literal> </Entry>
<Entry> <Literal>HsStablePtr</Literal> </Entry>
<Entry> void* (8) </Entry>
<Entry> </Entry>
<ListItem>
<Para>
-Foreign objects are handled like <Literal>Addr</Literal> by the FFI, so there
-is again the guarantee that <Literal>HsForeignObj</Literal> is the same as
+Foreign objects are handled like <Literal>Ptr</Literal> by the FFI, so there
+is again the guarantee that <Literal>HsForeignPtr</Literal> is the same as
<Literal>void*</Literal>. The separate name is meant as a reminder that there is
a finalizer attached to the object pointed to.
</Para>
</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
<ProgramListing>
-foreign import "mumble" mumble :: ForeignObj -> IO ()
+foreign import "mumble" mumble :: ForeignPtr a -> IO ()
-f :: Addr -> IO ()
+f :: Ptr a -> IO ()
f ptr = do
fo <- newForeignObj ptr myFinalizer
mumble fo
</ProgramListing>
-The <Literal>ForeignObj</Literal> must live across the call to <Function>mumble</Function> even if
-it is not subsequently used/reachable. Why the insistence on this?
-Consider what happens if <Function>mumble</Function> calls a function which calls back
-into the Haskell world to execute a function, behind our back as it
-were. This evaluation may possibly cause a garbage collection, with
-the result that <Literal>fo</Literal> may end up being finalised.
+The <Literal>ForeignPtr</Literal> must live across the call to
+<Function>mumble</Function> even if it is not subsequently
+used/reachable. Why the insistence on this? Consider what happens if
+<Function>mumble</Function> calls a function which calls back into the
+Haskell world to execute a function, behind our back as it were. This
+evaluation may possibly cause a garbage collection, with the result
+that <Literal>fo</Literal> may end up being finalised.
-By guaranteeing that <Literal>fo</Literal> will be considered live across the call
-to <Function>mumble</Function>, the unfortunate situation where <Literal>fo</Literal> is finalised
-(and hence the reference passed to <Function>mumble</Function> is suddenly no longer
+By guaranteeing that <Literal>fo</Literal> will be considered live
+across the call to <Function>mumble</Function>, the unfortunate
+situation where <Literal>fo</Literal> is finalised (and hence the
+reference passed to <Function>mumble</Function> is suddenly no longer
valid) is avoided.
</Sect1>
-<Sect1 id="sec-prim-dynamic">
+<Sect1 id="sec-ffi-prim-dynamic">
<Title>Invoking external functions via a pointer
</Title>
: ...
..
| 'foreign' 'import' [callconv] 'dynamic' ['unsafe']
- varid :: Addr -> (prim_args -> IO prim_result)
+ varid :: Addr -> (prim_args -> IO prim_result)
</ProgramListing>
</Para>
</Sect1>
-<Sect1 id="sec-entry">
+<Sect1 id="sec-ffi-entry">
<Title>Exposing Haskell functions
</Title>
<Para>
<ProgramListing>
-foreign export ccall "foo" bar :: Int -> Addr -> IO Double
+foreign export ccall "foo" bar :: Int -> Addr -> IO Double
</ProgramListing>
</Para>
<ProgramListing>
- f :: Num a => a -> a
- foreign export ccall "fInt" f :: Int -> Int
- foreign export ccall "fFloat" f :: Float -> Float
+ f :: Num a => a -> a
+ foreign export ccall "fInt" f :: Int -> Int
+ foreign export ccall "fFloat" f :: Float -> Float
</ProgramListing>
</Para>
-<Sect2 id="sec-callback">
+<Sect2 id="sec-ffi-callback">
<Title>Exposing Haskell function values
</Title>
topdecl
: ...
..
- | 'foreign' 'export' [callconv] 'dynamic' varid :: prim_type -> IO Addr
+ | 'foreign' 'export' [callconv] 'dynamic' varid :: prim_type -> IO Addr
</ProgramListing>
</Para>
<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>
<Para>
<ProgramListing>
-foreign export dynamic mkCallback :: (Int -> IO Int) -> IO Addr
+foreign export dynamic mkCallback :: (Int -> IO Int) -> IO Addr
-foreign import registerCallback :: Addr -> IO ()
+foreign import registerCallback :: Addr -> IO ()
-exportCallback :: (Int -> IO Int) -> IO ()
+exportCallback :: (Int -> IO Int) -> IO ()
exportCallback f = do
fx <- mkCallback f
registerCallback fx
<Para>
<ProgramListing>
-Foreign.freeHaskellFunctionPtr :: Addr -> IO ()
+Foreign.freeHaskellFunctionPtr :: Addr -> IO ()
</ProgramListing>
</Para>
</Sect2>
-<Sect2 id="sec-foreign-label">
+<Sect2 id="sec-ffi-foreign-label">
<Title>Code addresses
</Title>
</Sect1>
<!-- This doesn't need to be seen in the docs
-<Sect1 id="sec-changelog">
+<Sect1 id="sec-ffi-changelog">
<Title>Change history
</Title>
<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>
-is the widest possible data pointer.
+changed the C representation of
+<Literal>Haskell_ForeignPtr</Literal> from
+<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>