{#fun [pure] [unsafe] cid [as (hsid | ^)]
[ctxt =>] { parm1 , ... , parmn } -> parm
Function hooks are call hooks including parameter marshalling. Thus, the
components of a function hook up to and including the as
alias are the
same as for call hooks. However, an as
alias has a different meaning; it
specifies the name of the generated Haskell function. The remaining
components use literals enclosed in backwards and foward single quotes (`
and '
) to denote Haskell code fragments (or more precisely, parts of the
Haskell type signature for the bound function). The first one is the phrase
ctxt preceding =>
, which denotes the type context. This is followed
by zero or more type and marshalling specifications parm1 to parmn
for the function arguments and one parm for the function result. Each
such specification parm has the form
[inmarsh [* | -]] hsty [&] [outmarsh [*] [-]]
where hsty is a Haskell code fragment denoting a Haskell type. The optional information to the left and right of this type determines the marshalling of the corresponding Haskell value to and from C; they are called the in and out marshaller, respectively.
Each marshalling specification parm corresponds to one or two arguments
of the C function, in the order in which they are given. A marshalling
specification in which the symbol &
follows the Haskell type corresponds
to two C function arguments; otherwise, it corresponds only to one argument.
The parm following the left arrow ->
determines the marshalling of
the result of the C function and may not contain the symbol &
.
The *-
output marshal specification is for monadic actions that
must be executed but whose results are discarded. This is very useful
for e.g. checking an error value and throwing an exception if needed.
Both inmarsh and outmarsh are identifiers of Haskell marshalling
functions. By default they are assumed to be pure functions; if they have to
be executed in the IO
monad, the function name needs to be followed by a
star symbol *
. Alternatively, the identifier may be followed by a minux
sign -
, in which case the Haskell type does not appear as an
argument (in marshaller) or result (out marshaller) of the generated Haskell
function. In other words, the argument types of the Haskell function is
determined by the set of all marshalling specifications where the in
marshaller is not followed by a minus sign. Conversely, the result tuple of
the Haskell function is determined by the set of all marshalling
specifications where the out marshaller is not followed by a minus sign. The
order of function arguments and components in the result tuple is the same as
the order in which the marshalling specifications are given, with the exception
that the value of the result marshaller is always the first component in the
result tuple if it is included at all.
For a set of commonly occuring Haskell and C type combinations, default
marshallers are provided by C->Haskell if no explicit marshaller is
given. The out marshaller for function arguments is by default void-
.
The defaults for the in marshallers for function arguments are as follows:
Bool
and integral C type (including chars): cFromBool
cIntConv
cFloatConv
String
and char*
: withCString*
String
and char*
with explicit length: withCStringLen*
*
: with*
*
where T is an integral type:
withIntConv*
*
where T is a floating type:
withFloatConv*
Bool
and T*
where T is an integral type:
withFromBool*
The defaults for the out marshaller of the result are the converse of the
above; i.e., instead of the with
functions, the corresponding peek
functions are used. Moreover, when the Haskell type is ()
, the default
marshaller is void-
.
As an example, consider
{#fun notebook_query_tab_label_packing as ^
`(NotebookClass nb, WidgetClass cld)' =>
{notebook `nb' ,
widget `cld' ,
alloca- `Bool' peekBool*,
alloca- `Bool' peekBool*,
alloca- `PackType' peekEnum*} -> `()'#}
which results in the Haskell type signature
notebookQueryTabLabelPacking :: (NotebookClass nb, WidgetClass cld)
=> nb -> cld -> IO (Bool, Bool, PackType)
which binds the following C function:
void gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
GtkWidget *child,
gboolean *expand,
gboolean *fill,
GtkPackType *pack_type);