haskell - qué - software enlazadores de codigo
Problema del enlazador en tiempo de ejecución de GHCi al usar declaraciones FFI (1)
Esta es una limitación conocida de archivos dinámicos de objetos de enlace en el intérprete de códigos de bytes, GHCi.
Si carga código compilado que estaba enlazado estáticamente contra un objeto C dado, y luego también interpreta algo de Haskell sobre la marcha que también hace referencia a través del FFI al mismo objeto C, el enlazador de tiempo de ejecución se verá obligado a cargar el objeto C dinámicamente.
Ahora tiene dos versiones del símbolo C en su espacio de direcciones, y se producen fallas.
Debe interpretar todo en modo GHCi o abandonar el uso de GHCi para este proceso. Para algunos enlazadores OS, puede exponer la tabla de símbolos enlazados estáticamente a través de la tabla dinámica, (el -x
).
Tengo un problema con respecto a FFI en Haskell y el modo interactivo de GHC again .
Considere FFISo.hs
:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import qualified Data.ByteString.Char8 as B
import FFIFun.Foo
main :: IO ()
main = do
B.putStrLn "main"
callMeFromC
callMeFromHaskell
return ()
cc
:
#include <stdio.h>
void callMeFromC(void);
void callMeFromHaskell(void)
{
printf("callMeFromHaskell/n");
callMeFromC();
}
FFIFun/Foo.hs
:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module FFIFun.Foo where
import qualified Data.ByteString.Char8 as B
foreign import ccall "callMeFromHaskell"
callMeFromHaskell :: IO ()
foreign export ccall callMeFromC :: IO ()
callMeFromC :: IO ()
callMeFromC = B.putStrLn "callMeFromC"
y un Makefile
:
SHELL := bash
GHC_OPT := -Wall -O2 -fno-warn-unused-do-bind
all: ffiso
test: ffiso
./$<
ffiso: FFISo.hs c.c
ghc --make $(GHC_OPT) $^ -o $@
clean:
rm -rf *{.hi,o,_stub.*} ffiso FFIFun/*{.hi,.o,_stub.*}
ghci: ffiso
ghci -package bytestring FFIFun/Foo.o c.o FFISo.hs
lo encuentras también aquí como una esencia .
Entonces, mi problema ahora:
$ make ghci
[...]
Ok, modules loaded: Main, FFIFun.Foo.
Prelude Main> -- fine, it''s loading.
Prelude Main> :t callMeFromC
<interactive>:1:1: Not in scope: `callMeFromC''
Prelude Main> -- uhm, why?
Prelude Main> :t main
main :: IO ()
Prelude Main> main
GHCi runtime linker: fatal error: I found a duplicate definition for symbol
FFIFunziFoo_callMeFromC_info
whilst processing object file
./FFIFun/Foo.o
This could be caused by:
* Loading two different object files which export the same symbol
* Specifying the same object file twice on the GHCi command line
* An incorrect `package.conf'' entry, causing some object to be
loaded twice.
GHCi cannot safely continue in this situation. Exiting now. Sorry.
Hrmpf, ¿qué está mal aquí? Curiosamente, recibo un error diferente en i686
(más arriba, es un sistema x86_64
, pero ambos son GHC 7.4.1):
GHCi runtime linker: fatal error: I found a duplicate definition for symbol
__stginit_FFIFunziFoo
whilst processing object file
./FFIFun/Foo.o
This could be caused by:
* Loading two different object files which export the same symbol
* Specifying the same object file twice on the GHCi command line
* An incorrect `package.conf'' entry, causing some object to be
loaded twice.
GHCi cannot safely continue in this situation. Exiting now. Sorry.
Además, ¿hay alguna documentación al respecto? Siento que soy el único que tiene problemas con FFI y GHCi.
editar: nota, que la make test
funciona bien:
$ ghc --make -Wall -O2 -fno-warn-unused-do-bind FFISo.hs c.c -o ffiso
[1 of 2] Compiling FFIFun.Foo ( FFIFun/Foo.hs, FFIFun/Foo.o )
[2 of 2] Compiling Main ( FFISo.hs, FFISo.o )
Linking ffiso ...
./ffiso
main
callMeFromC
callMeFromHaskell
callMeFromC