2012-01-11 10 views
6

からHaskellライブラリをインポート呼び出しHaskellのモジュールはのは、Haskellの関数はCの関数から呼び出すことができますどのように一般的な例を見てみましょう:GHC/FFI:C

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 

そして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 

そして、それが今、私のために、OKではありませんエラーが表示されます。 a bug in GHCchangeset (more formal description of the bug)

私はGHC-6.12.3を使用するように、私はすでにこの機能は実装されているが、次のように:

$ ...undefined reference to `__stginit_bytestringzm0zi9zi2zi0_DataziByteStringziChar8_' 

私は現在の問題に発見したすべてのはこれです。だから私はどのように問題を解決するか分からない。

おそらく、共有ライブラリを作成し、それをCモジュールと動的にリンクする方が簡単でしょうか?

+1

チェンジセットが6.12.3より新しいので、6.12で 'hs_add_root'を呼び出す必要があります。それは7.0にすることさえできませんでした。 –

答えて

4

私はバグが関係しているとは思わない。 --makeを試しましたか?

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

これらのエラーは、エラーの種類は、あなたが1--makeを使用せずにパッケージの依存関係を持つ純粋なHaskellコードをリンクする際に取得するために使用されています。デフォルトではGHCはbaseにリンクしていますが、動作しない別のパッケージのものが必要な場合に使用します。

あなたはより多くの「マニュアル」方法たい場合は、明示的にパッケージを指定して試みることができる:

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

をGHC 7、--makeがデフォルトとなっているので。

+0

ありがとう、これは私が必要とするものなので、簡単です:)そして、私はそれをリンクしようと多くの時間を無駄にしました。 – skvadrik

+0

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

+0

私は答えを作業コマンドで更新しました:) – ehird