The compiler uses two non-standard type-classes when
type-checking the arguments and results of `_ccall_': the arguments
(respectively result) of `_ccall_' must be instances of the class
`CCallable' (respectively `CReturnable'). Both classes may be
imported from the module `CCall', but this should only be necessary if
you want to define a new instance. (Neither class defines any methods
-- their only function is to keep the type-checker happy.)
The type checker must be able to figure out just which of the
C-callable/returnable types is being used. If it can't, you have to
add type signatures. For example,
f x = _ccall_ foo x
is not good enough, because the compiler can't work out what type `x' is, nor
what type the `_ccall_' returns. You have to write, say:
f :: Int -> IO Double
f x = _ccall_ foo x
This table summarises the standard instances of these classes.
Type CCallable CReturnable Which is probably...
----------------------------------------------------------------------------------------
`Char' Yes Yes `unsigned char'
`Int' Yes Yes `long int'
`Word' Yes Yes `unsigned long int'
`Addr' Yes Yes `char *'
`Float' Yes Yes `float'
`Double' Yes Yes `double'
`()' No Yes `void'
`[Char]' Yes No `char *' (null-terminated)
`Array' Yes No `unsigned long *'
`ByteArray' Yes No `unsigned long *'
`MutableArray' Yes No `unsigned long *'
`MutableByteArray' Yes No `unsigned long *'
`State' Yes Yes nothing!
`StablePtr' Yes Yes `unsigned long *'
`ForeignObjs' Yes Yes see later
The brave and careful programmer can add their own instances of these
classes for the following types:
-
A boxed-primitive type may be made an instance of both
`CCallable' and `CReturnable'.
A boxed primitive type is any data type with a
single unary constructor with a single primitive argument. For
example, the following are all boxed primitive types:
Int
Double
data XDisplay = XDisplay Addr#
data EFS a = EFS# ForeignObj#
instance CCallable (EFS a)
instance CReturnable (EFS a)
-
Any datatype with a single nullary constructor may be made an
instance of `CReturnable'. For example:
data MyVoid = MyVoid
instance CReturnable MyVoid
-
As at version 2.09, `String' (i.e., `[Char]') is still
not a `CReturnable' type.
Also, the now-builtin type `PackedString' is neither
`CCallable' nor `CReturnable'. (But there are functions in
the PackedString interface to let you get at the necessary bits...)