調用哈斯克爾模塊讓我們以一個常見的例子是如何Haskell的函數可以從C函數調用:GHC/FFI:其中進口哈斯克爾庫由C
哈斯克爾模塊:
{-# 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
與C模塊:
#include <HsFFI.h>
#ifdef __GLASGOW_HASKELL__
#include "Safe_stub.h"
extern void __stginit_Safe(void);
#endif
#include <stdio.h>
int main(int argc, char *argv[]) {
int i;
hs_init(&argc, &argv);
#ifdef __GLASGOW_HASKELL__
hs_add_root(__stginit_Safe);
#endif
i = fibonacci_hs(42);
printf("Fibonacci: %d\n", i);
hs_exit();
return 0;
}
我編譯和鏈接它:
$ ghc -c -O Safe.hs
$ ghc test.c Safe.o Safe_stub.o -o test
沒關係。但是如果我需要在Haskell模塊中導入一些庫,該怎麼辦?例如,如果我需要使用字節串,我要補充「進口Data.Bytestring.Char8」(該模塊是採取一個例子,在代碼中不使用):
{-# LANGUAGE ForeignFunctionInterface #-}
module Safe where
import Foreign.C.Types
import Data.Bytestring.Char8
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
而且那也不行,現在我得到一個錯誤:
$ ...undefined reference to `__stginit_bytestringzm0zi9zi2zi0_DataziByteStringziChar8_'
所有我目前發現問題是: a bug in GHC當我使用GHC-6.12.3如下 changeset (more formal description of the bug)
,我已經實現了這個功能。所以我不知道如何解決這個問題。
也許,製作共享庫並將其與我的C模塊動態鏈接會更容易?
變更集比6.12.3更新,所以你仍然需要用6.12調用'hs_add_root'。它甚至沒有達到7.0。 – 2012-01-11 16:20:37