My main reference is : http://mostlycode.wordpress.com/2010/01/03/shared-haskell-so-library-with-ghc-6-10-4-and-cabal/
Step 1: Write your Haskell code
{-# LANGUAGE ForeignFunctionInterface #-}
module GfxHaskellExt where
import Foreign
import Foreign.C.Types
foreign export ccall "my_haskell_call" my_haskell_call :: CInt -> IO ()
my_haskell_call :: CInt -> IO()
my_haskell_call n = do
putStrLn "It is a HI from Haskell. Hello C"
print (n + 250)
Step 2: Write initialization\finalization functions for Haskell dll in C
(directly from http://mostlycode.wordpress.com/2010/01/03/shared-haskell-so-library-with-ghc-6-10-4-and-cabal/)
#define CAT(a,b) XCAT(a,b)
#define XCAT(a,b) a ## b
#define STR(a) XSTR(a)
#define XSTR(a) #a
#include <HsFFI.h>
extern void CAT (__stginit_, MODULE) (void);
static void library_init (void) __attribute__ ((constructor));
static void library_init (void)
{
/* This seems to be a no-op, but it makes the GHCRTS envvar work. */
static char *argv[] = { STR (MODULE) ".dll", 0 }, **argv_ = argv;
static int argc = 1;
hs_init (&argc, &argv_);
hs_add_root (CAT (__stginit_, MODULE));
}
static void library_exit (void) __attribute__ ((destructor));
static void library_exit (void)
{
hs_exit ();
}
Step 3: Write .cabal file: (Here we build it as a DLL). Please make sure MODULE name matches the module name in your Haskell src above.
name: my-haskell-exts
version: 0.3.0
license: BSD3
copyright: (c) Intel Corporation
author: John Doe
maintainer: John Doe <[email protected]>
stability: experimental
synopsis: Test Dll
description: Experimental project
category: Test
build-type: Simple
cabal-version: >= 1.6
executable HaskellExts.dll
build-depends: base == 4.*
hs-source-dirs: src
ghc-options: -optl-shared -optc-DMODULE=GfxHaskellExt -no-hs-main
main-is: HaskellExts.hs
c-sources: src/module_init.c
include-dirs: src
install-includes: HaskellExts.h
cc-options: -DMODULE=GfxHaskellExt -shared
ld-options: -shared
- Pur your src files (.hs, .c) in a folder named 'src', and put .cabal in the same folder.
- In cmd.exe, run 'cabal configure' first, if succeded, run 'cabal build'
Step 5: Write your C application from which you wanna use Haskell code:
#include "windows.h"
typedef void (_cdecl* HsCalltype)(int);
int main()
{
HMODULE dllHandle = LoadLibrary("HaskellExts.dll");
if (dllHandle != NULL)
{
HsCalltype pfunc = (HsCalltype)GetProcAddress(dllHandle, "my_haskell_call");
if(pfunc != NULL)
{
pfunc(100);
}
FreeLibrary(dllHandle);
}
return 0;
}
Please note: use "_cdecl" to declare the Haskell function. And, TADA !