Primitive FFI in nhc98

The nhc98 compiler contains an implementation of the primitive foreign function interface that is also available in STG-Hugs and ghc. The specification of the low-level FFI is at

We also supply a version of the proposed standard FFI libraries which add a layer of useful functions on top of the basic mechanism. The signature of nhc98's FFI library is here. You can use this library in nhc98 by adding import FFI to your programs.

nhc98-specific notes

  • In a foreign import specification, the external location string is currently ignored. nhc98 does not yet support dynamic linking, and it has no real meaning for completely static linking.
  • For the same reason, foreign import dynamic and foreign export dynamic are not yet supported.
  • The calling convention stdcall is ignored; nhc98 only works on ccall platforms anyway.
  • The annotation unsafe is ignored; it only applies to ghc, and is irrelevant for nhc98.
  • Extra annotations are provided. cast indicates that an arity-1 foreign import is only being used for its type-cast, and hence eliminates some runtime overheads:
      foreign import floatToDouble cast :: Float -> Double 
    and noproto tells the compiler not to generate a C function prototype for the external function:
      foreign import sin noproto :: Float -> Float 
    eliminates the normal generation of
      extern float sin (float); 
    for occasions when such a declaration might conflict with a #include'd declaration.
  • The set of primitive types allowed across the FFI is slightly larger than the standard set in nhc98: we allow PackedString to be passed - these are genuine null-terminated C-style strings. Used as a result type, the string is copied into the Haskell heap (allowing the original pointer to be freed safely); used as an argument type, a pointer to the heap-allocated string is passed to C (i.e. do not free it!).
  • Additionally, we allow any non-primitive datatype to be passed across the FFI (but give a Warning for each one) as a heap pointer. This feature should only be used by serious implementers, because any foreign code manipulating non-primitive data must use nhc98's internal heap format.
  • A foreign export specification is treated as the actual type signature for the exported function. You are not allowed a second (possibly more general) type signature.
  • Hence, you cannot foreign export any function that requires a class dictionary.
  • foreign label is not yet supported.
  • Explicitly sized types such as Int8 exist, but they are not fully supported with instances of Num, Eq, etc.

The latest updates to these pages are available on the WWW from

This page last modified: 2001.11.28
York Functional Programming Group