Ho un problema riguardante l'FFI in Haskell e la modalità interattiva di GHC again.Problema di collegamento del runtime GHCi durante l'uso delle dichiarazioni FFI
consideri 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()
c.c
:
#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"
e 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 [email protected]
clean:
rm -rf *{.hi,o,_stub.*} ffiso FFIFun/*{.hi,.o,_stub.*}
ghci: ffiso
ghci -package bytestring FFIFun/Foo.o c.o FFISo.hs
lo trovi anche here as a gist.
Quindi, il mio problema ora:
$ 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, che cosa è sbagliato? È interessante notare che ottengo un errore diverso su i686
(sopra, si tratta di un sistema di x86_64
, ma entrambi 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.
Inoltre, c'è qualche documentazione a riguardo? Mi sento come se fossi l'unico ad avere momenti difficili con FFI e GHCi là fuori.
edit: nota, che make test
funziona bene:
$ 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
È possibile entrare in situazioni se si tenta di collegare staticamente un modulo a un simbolo FFI; e anche caricarlo dinamicamente. –
puoi elaborare? o come si può risolvere questo? –
Ho giocato un po 'con esso e sembra essere un bug in GHCi. Il simbolo viene esaminato due volte: una volta perché viene caricato sulla riga di comando tramite il file .o e una volta perché viene caricato il file .hs. Sembra. Forse non dovrebbe collegarsi affatto all'avvio di ghci, ma solo quando si eseguono cose? –