Calling Haskell from C

From HaskellWiki
Revision as of 17:08, 27 June 2019 by Perevezentsev (talk | contribs) (Delete lines in C file which prevents linking in GHC 8.6.5 (apparently not needed anymore))

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

It is not uncommon to want to call a Haskell function from C code. Here's how to do that.

We define the fibonacci function in Haskell:

{-# LANGUAGE ForeignFunctionInterface #-}

module Safe where

import Foreign.C.Types

fibonacci :: Int -> Int
fibonacci n = fibs !! n
    where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral

foreign export ccall fibonacci_hs :: CInt -> CInt

Note the foreign export. When GHC sees this, it will generate stubs for C, to help it work out the Haskell types.

And call it from C:

#include <HsFFI.h>
#include "Safe_stub.h"
#include <stdio.h>

int main(int argc, char *argv[])
    int i;
    hs_init(&argc, &argv);

    i = fibonacci_hs(42);
    printf("Fibonacci: %d\n", i);

    return 0;

Now, first compile the Haskell file:

$ ghc -c -O Safe.hs

Which creates Safe_stub.c, Safe_stub.o, Safe_stub.h, which you import into your C program. Now compile your C code with ghc (!), passing the Haskell objects on the command line:

If GHC version < 7.2

$ ghc -optc-O test.c Safe.o Safe_stub.o -o test


$ ghc --make -no-hs-main -optc-O test.c Safe -o test

Then run your C code:

$ ./test 
Fibonacci: 267914296

And that's it.