2. Calling foreign functions

To bind a Haskell variable name and type to an external function, we introduce a new construct: foreign import. It defines the type of a Haskell function together with the name of an external function that actually implements it. The syntax of foreign import construct is as follows:

topdecl 
  : ...
  ..
  | 'foreign' 'import' [callconv] [ext_fun] ['unsafe'] varid '::' prim_type

A foreign import declaration is only allowed as a toplevel declaration. It consists of two parts, one giving the Haskell type (prim_type), Haskell name (varid) and a flag indicating whether the primitive is unsafe, the other giving details of the name of the external function (ext_fun) and its calling interface (callconv.)

Giving a Haskell name and type to an external entry point is clearly an unsafe thing to do, as the external name will in most cases be untyped. The onus is on the programmer using foreign import to ensure that the Haskell type given correctly maps on to the type of the external function. Section 2.5 specifies the mapping from Haskell types to external types.

2.1. Giving the external function a Haskell name

The external function has to be given a Haskell name. The name must be a Haskell varid, so the language rules regarding variable names must be followed, i.e., it must start with a lower case letter followed by a sequence of alphanumeric (`in the Unicode sense') characters or '. [1]

varid : small ( small | large | udigit | ' )*

2.2. Naming the external function

The name of the external function is a string:

ext_fun  : string

For example,

foreign import stdcall "RegCloseKey" regCloseKey :: Ptr a -> IO ()

states that the external function named RegCloseKey should be bound to the Haskell name regCloseKey.

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).

If the Haskell name of the imported function is identical to the external name, the ext_fun can be omitted. e.g.:

foreign import sin :: Double -> IO Double

is identical to

foreign import "sin" sin :: Double -> IO Double

2.3. Calling conventions

The number of calling conventions supported is fixed:

callconv : ccall | stdcall

Some remarks:

2.4. External function types

The range of types that can be passed as arguments to an external function is restricted (as are the range of results coming back):

prim_type : IO prim_result
          | prim_result
          | prim_arg '->' prim_type

Section 2.4.2 defines prim_result; Section 2.4.1 defines prim_arg.

2.4.1. Argument types

The external function expects zero or more arguments. The set of legal argument types is restricted to the following set:

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
       | Ptr a    | Char    | StablePtr a
       | Bool

int_ty       : Int   | Int8   | Int16   | Int32 | Int64
word_ty      : Word8 | Word16 | Word32  | Word64
float_ty     : Float | Double

  • ext_ty represent the set of basic types supported by C-like languages, although the numeric types are explicitly sized. The stable pointer StablePtr type looks out of place in this list of C-like types, but it has a well-defined and simple C mapping, see Section 2.5 for details.

  • prim_arg represent the set of permissible argument types. In addition to ext_ty, ForeignPtr is also included. The ForeignPtr type represent values that are pointers to some external entity/object. It differs from the Ptr type in that ForeignPtrs are finalized, i.e., once the garbage collector determines that a ForeignPtr is unreachable, it will invoke a finalising procedure attached to the ForeignPtr to notify the outside world that we're through with using it.

  • Haskell newtypes that wrap up a prim_arg type can also be passed to external functions.

  • Haskell type synonyms for any of the above can also be used in foreign import declarations. Qualified names likewise, i.e. Word.Word32 is legal.

  • foreign import does not support the binding to external constants/variables. A foreign import declaration that takes no arguments represent a binding to a function with no arguments.

  • A GHC extension is the support for unboxed types:
    prim_arg : ...  | unboxed_h_ty
    ext_ty   : .... | unboxed_ext_ty
    
    unboxed_ext_ty : Int#   | Word#    | Char#
                   | Float# | Double#  | Addr# 
    	       | StablePtr# a
    unboxed_h_ty : MutableByteArray# | ForeignObj#
                 | ByteArray#
    Clearly, if you want to be portable across Haskell systems, using system-specific extensions such as this is not advisable; avoid using them if you can. (Support for using unboxed types might be withdrawn sometime in the future.)

2.5. Type mapping

For the FFI to be of any practical use, the properties and sizes of the various types that can be communicated between the Haskell world 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 Table 1 defines the mapping between Haskell and C types.

Some remarks:

  1. A Haskell system that implements the FFI will supply a header file HsFFI.h that includes target platform specific definitions for the above types and values.

  2. The sized numeric types Hs{Int,Word}{8,16,32,64} have a 1-1 mapping to ISO C 99's {,u}int{8,16,32,64}_t. For systems that doesn't support this revision of ISO C, a best-fit mapping onto the supported C types is provided.

  3. An implementation which does not support 64 bit integral types on the C side should implement Hs{Int,Word}64 as a struct. In this case the bounds HS_INT64_{MIN,MAX} and HS_WORD64_MAX are undefined.

  4. A valid Haskell representation of Int has to be equal to or wider than 30 bits. The HsInt synonym is guaranteed to map onto a C type that satisifies Haskell's requirement for Int.

  5. It is guaranteed that Hs{Float,Double} are one of C's floating-point types float/double/long double.

  6. It is guaranteed that HsAddr is of the same size as void*, so any other pointer type can be converted to and from HsAddr without any loss of information (K&R, Appendix A6.8).

  7. Foreign objects are handled like Ptr by the FFI, so there is again the guarantee that HsForeignPtr is the same as void*. The separate name is meant as a reminder that there is a finalizer attached to the object pointed to.

  8. Stable pointers are passed as addresses by the FFI, but this is only because a void* is used as a generic container in most APIs, not because they are real addresses. To make this special case clear, a separate C type is used here.

  9. The bounds are preprocessor macros, so they can be used in #if and for array bounds.

  10. Floating-point limits are a little bit more complicated, so preprocessor macros mirroring ISO C's float.h are provided:
    HS_{FLOAT,DOUBLE}_RADIX
    HS_{FLOAT,DOUBLE}_ROUNDS
    HS_{FLOAT,DOUBLE}_EPSILON
    HS_{FLOAT,DOUBLE}_DIG
    HS_{FLOAT,DOUBLE}_MANT_DIG
    HS_{FLOAT,DOUBLE}_MIN
    HS_{FLOAT,DOUBLE}_MIN_EXP
    HS_{FLOAT,DOUBLE}_MIN_10_EXP
    HS_{FLOAT,DOUBLE}_MAX
    HS_{FLOAT,DOUBLE}_MAX_EXP
    HS_{FLOAT,DOUBLE}_MAX_10_EXP

  11. It is guaranteed that Haskell's False/True map to C's 0/1, respectively, and vice versa. The mapping of any other integral value to Bool is left unspecified.

  12. To avoid name clashes, identifiers starting with Hs and macros starting with HS_ are reserved for the FFI.

  13. GHC only: The GHC specific types ByteArray and MutableByteArray both map to char*.

2.6. Some foreign import wrinkles

Notes

[1]

Notice that with Haskell 98, underscore ('_') is included in the character class small.

[2]

The stdcall is a Microsoft Win32 specific wrinkle; it's used throughout the Win32 API, for instance. On platforms where stdcall isn't meaningful, it should be treated as being equal to ccall.