Chúng ta hãy ví dụ phổ biến như thế nào một hàm Haskell có thể được gọi từ một hàm C:GHC/FFI: gọi mô-đun Haskell đó nhập khẩu các thư viện Haskell từ C
Haskell mô-đun:
{-# 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
Và mô-đun 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;
}
tôi biên dịch và liên kết nó:
$ ghc -c -O Safe.hs
$ ghc test.c Safe.o Safe_stub.o -o test
OK. Nhưng nếu tôi cần nhập một số thư viện trong mô-đun haskell thì sao? Ví dụ, nếu tôi cần phải sử dụng bytestrings tôi nên thêm "Data.Bytestring.Char8 nhập khẩu" (mô-đun này được thực hiện cho một ví dụ và không được sử dụng trong mã):
{-# 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
Và đó không phải là ok, bây giờ tôi nhận được một lỗi:
$ ...undefined reference to `__stginit_bytestringzm0zi9zi2zi0_DataziByteStringziChar8_'
Tất cả tôi đã tìm thấy trên hiện vấn đề là thế này: a bug in GHC và như sau changeset (more formal description of the bug)
như tôi đã sử dụng GHC-6.12.3, tôi đã có tính năng này thực hiện. Vì vậy, tôi không có ý tưởng làm thế nào để khắc phục vấn đề.
Có thể sẽ dễ dàng hơn khi tạo thư viện được chia sẻ và liên kết động với thư viện C của tôi?
Thay đổi mới hơn 6.12.3, vì vậy bạn vẫn phải gọi 'hs_add_root' với 6.12. Nó thậm chí không làm cho nó thành 7,0. –