Рассмотрим обычный пример, как функция haskell может быть вызвана из функции 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
#ifdef __GLASGOW_HASKELL__
#include "Safe_stub.h"
extern void __stginit_Safe(void);
#endif
#include
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? Например, если мне нужно использовать байтстринги, я должен добавить "import 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_'
Все, что я нашел по этой проблеме, это: ошибка в GHC и следующее. changeset (более формальное описание ошибки)
Поскольку я использую ghc-6.12.3, у меня уже реализована эта возможность. Поэтому у меня нет идей, как исправить проблему.
Возможно, было бы проще сделать разделяемую библиотеку и динамически связать ее с моим модулем C?