software qué programación paradigma integrados informatica entornos enlazadores ejemplos desarrollo depuradores compiladores codigo haskell linker ffi ghci

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