2012-01-11 16 views
6

調用哈斯克爾模塊讓我們以一個常見的例子是如何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模塊動態鏈接會更容易?

+1

變更集比6.12.3更新,所以你仍然需要用6.12調用'hs_add_root'。它甚至沒有達到7.0。 – 2012-01-11 16:20:37

回答

4

我不認爲這個bug是相關的。您是否嘗試過使用--make

$ ghc -c -O Safe.hs 
$ ghc --make test.c Safe.o Safe_stub.o -o test 

這些錯誤,你用錯誤的種類來獲得聯用軟件包的依賴純Haskell代碼時不使用--make; GHC鏈接默認爲base,但是如果您需要其他不起作用的軟件包中的任何內容。

您也可以嘗試明確指定的包,如果你想有一個更「手冊」的方法:

$ ghc -c -O Safe.hs 
$ ghc -package bytestring test.c Safe.o Safe_stub.o -o test 

由於GHC 7,--make已經默認。

+0

謝謝,這正是我所需要的,太簡單了:)而且我浪費了很多小時試圖鏈接它。 – skvadrik 2012-01-11 16:18:29

+0

'$ ghc -c -O Safe.hs' '$ ghc -package bytestring test.c Safe.o Safe_stub.o -o test' – skvadrik 2012-01-11 16:32:36

+0

我已經用工作命令更新了我的答案:) – ehird 2012-01-11 16:34:27