Go to the first, previous, next, last section, table of contents.

`_ccall_' and `_casm_': an introduction

The simplest way to use a simple C function

double fooC( FILE *in, char c, int i, double d, unsigned int u )
is to provide a Haskell wrapper
fooH :: Char -> Int -> Double -> _Word -> PrimIO Double
fooH c i d w = _ccall_ fooC "stdin" c i d w
The function `fooH' will unbox all of its arguments, call the C function `fooC' and box the corresponding arguments.

So, if you want to do C-calling, you have to confront the underlying Glasgow I/O system. It's just your typical monad whatnot.

One of the annoyances about `_ccall_'s is when the C types don't quite match the Haskell compiler's ideas. For this, the `_casm_' variant may be just the ticket (NB: no chance of such code going through a native-code generator):

oldGetEnv name
  = _casm_ "%r = getenv((char *) %0);" name `thenPrimIO` \ litstring@(A# str#) ->
    returnPrimIO (
        if (litstring == "NULL") then
            Failure (SearchError ("GetEnv:"++name))
        else
            Str (unpackCString# str#)
    )

The first literal-literal argument to a `_casm_' is like a `printf' format: `%r' is replaced with the "result," `%0'--`%n-1' are replaced with the 1st--nth arguments. As you can see above, it is an easy way to do simple C casting. Everything said about `_ccall_' goes for `_casm_' as well.


Go to the first, previous, next, last section, table of contents.