Calling Haskell from C - (DLL solution)

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 


Step 4: Build your Haskell DLL:

- 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 !



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章