Tomemos un ejemplo común de cómo una función Haskell puede llamar desde una función C:GHC/FFI: llamando al módulo de Haskell que importa bibliotecas Haskell C
Haskell módulo:
{-# 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
y el módulo 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;
}
I de compilación y enlace que:
$ ghc -c -O Safe.hs
$ ghc test.c Safe.o Safe_stub.o -o test
Eso está bien. Pero, ¿qué ocurre si necesito importar alguna biblioteca en el módulo haskell? Por ejemplo, si tengo que usar cadenas de bytes debo añadir "Data.Bytestring.Char8 importación" (este módulo se toma como ejemplo y no se utiliza en el código):
{-# 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
Y eso no está bien, por ahora obtener un error:
$ ...undefined reference to `__stginit_bytestringzm0zi9zi2zi0_DataziByteStringziChar8_'
Todo lo que he encontrado actualmente en el problema es el siguiente: a bug in GHC y de la siguiente changeset (more formal description of the bug)
como utilizo GHC-6.12.3, ya tengo esta característica implementada. Entonces no tengo idea de cómo solucionar el problema.
Quizás, sería más fácil crear una biblioteca compartida y vincularla dinámicamente con mi módulo C?
El conjunto de cambios es más reciente que 6.12.3, por lo que aún tiene que llamar a 'hs_add_root' con 6.12. Ni siquiera llegó a 7.0. –