Primitive FFI in nhc98
The nhc98 compiler contains an implementation of the
standard foreign function interface that is also available
in Hugs and ghc. Version 1.16 implements the latest
standard syntax for foreign function declarations, as specified at:
http://www.cse.unsw.edu.au/~chak/haskell/ffi/
The FFI standard specifies both the basic mechanism as a language
extension, and a layer of libraries. The libraries contain many useful
datatypes and access functions, for instance to manage memory storage
in the foreign language. nhc98's implementation includes two versions
of these libraries: nhc98's internal FFI
library, and the standard
portable Foreign libraries. The latter collection departs from
the official standard only in the use of the hierarchical module
namespace instead of the official flat namespace.
Compliance notes
- Supported calling conventions are: ccall, noproto,
and cast.
Unsupported calling conventions are: stdcall, jvm,
dotnet, cplusplus.
- In a foreign import specification, the specification of a
C header file or library in the "external entity" string
is currently ignored. nhc98 does not use header files for
checking prototypes, and it does not yet support dynamic library linking.
- foreign import "wrapper" and foreign import "dynamic"
are not yet supported.
- The annotation unsafe is ignored and treated as if it were
safe; it is purely a speed optimisation for ghc.
- The annotation threadsafe has no special meaning in
nhc98, since it does not implement the concurrent threads
extension.
- Two non-standard calling conventions are provided.
cast indicates that an arity-1 foreign import is only being
used for its C type-cast, and hence eliminates some runtime overheads.
For example,
foreign import cast floatToDouble :: Float -> Double .
The calling convention noproto is essentially the same as
ccall but tells the compiler not to generate a C function
prototype for the external function. For example,
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 in nhc98 than the standard allowed set: 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!). However, we recommend you use the standard type
Foreign.C.String instead - it is more portable.
- 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.
The latest updates to these pages are available on the WWW from
http://www.haskell.org/nhc98/
This page last modified: 20 January 2003
York Functional Programming Group
|