# Foreign Function Interface
# Calling C from Haskell
For performance reasons, or due to the existence of mature C libraries, you may want to call C code from a Haskell program. Here is a simple example of how you can pass data to a C library and get an answer back.
foo.c:
#include <inttypes.h>
int32_t foo(int32_t a) {
return a+1;
}
Foo.hs:
import Data.Int
main :: IO ()
main = print =<< hFoo 41
foreign import ccall unsafe "foo" hFoo :: Int32 -> IO Int32
The unsafe keyword generates a more efficient call than 'safe', but requires that the C code never makes a callback to the Haskell system. Since foo is completely in C and will never call Haskell, we can use unsafe.
We also need to instruct cabal to compile and link in C source.
foo.cabal:
name: foo
version: 0.0.0.1
build-type: Simple
extra-source-files: *.c
cabal-version: >= 1.10
executable foo
default-language: Haskell2010
main-is: Foo.hs
C-sources: foo.c
build-depends: base
Then you can run:
> cabal configure
> cabal build foo
> ./dist/build/foo/foo
42
# Passing Haskell functions as callbacks to C code.
It is very common for C functions to accept pointers to other functions as arguments. Most popular example is setting an action to be executed when a button is clicked in some GUI toolkit library. It is possible to pass Haskell functions as C callbacks.
To call this C function:
void event_callback_add (Object *obj, Object_Event_Cb func, const void *data)
we first import it to Haskell code:
foreign import ccall "header.h event_callback_add"
callbackAdd :: Ptr () -> FunPtr Callback -> Ptr () -> IO ()
Now looking at how Object_Event_Cb is defined in C header, define what Callback is in Haskell:
type Callback = Ptr () -> Ptr () -> IO ()
Finally, create a special function that would wrap Haskell function of type Callback into a pointer FunPtr Callback:
foreign import ccall "wrapper"
mkCallback :: Callback -> IO (FunPtr Callback)
Now we can register callback with C code:
cbPtr <- mkCallback $ \objPtr dataPtr -> do
-- callback code
return ()
callbackAdd cpPtr
It is important to free allocated FunPtr once you unregister the callback:
freeHaskellFunPtr cbPtr
# Syntax
- foreign import ccall unsafe "foo" hFoo :: Int32 -> IO Int32 {- Imports a function named
fooin some object file, and defines the symbolhFoowhich can be called with Haskell code. -}
# Remarks
While cabal has support for including a C and C++ libraries in a Haskell package, there are a few bugs. First, if you have data (rather than a function) defined in b.o that is used in a.o, and list the C-sources: a.c, b.c, then cabal will be unable to find the data. This is documented in #12152 (opens new window). A workaround when using cabal is to reorder the C-sources list to be C-sources: b.c, a.c. This may not work when using stack, because stack always links the C-sources alphabetically, regardless of the order in which you list them.
Another issues is that you must surround any C++ code in header (.h) files with #ifdef __cplusplus guards. This is because GHC doesn't understand C++ code in header files. You can still write C++ code in header files, but you must surround it with guards.
ccall refers to the calling convention; currently ccall and stdcall (Pascal convention) are supported. The unsafe keyword is optional; this reduces overhead for simple functions but may cause deadlocks if the foreign function blocks indefinitely or has insufficient permission to execute1 (opens new window).