使用FFI声明时GHCi运行时链接程序问题

我对Haskell的FFI和GHC的交互模式有一个问题。

考虑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" 

和一个Makefile

 SHELL := bash GHC_OPT := -Wall -O2 -fno-warn-unused-do-bind all: ffiso test: ffiso ./$< ffiso: FFISo.hs cc ghc --make $(GHC_OPT) $^ -o $@ clean: rm -rf *{.hi,o,_stub.*} ffiso FFIFun/*{.hi,.o,_stub.*} ghci: ffiso ghci -package bytestring FFIFun/Foo.o co FFISo.hs 

你也可以在这里find它。

所以,我现在的问题是:

 $ 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,这里有什么问题? 有趣的是,我在i686上得到了一个不同的错误(上面是x86_64系统,但都是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. 

还有,有关于它的一些文件? 我觉得我是唯一一个在FFI和GHCi那里遇到困难的人。

编辑:注意, make test工作正常:

 $ ghc --make -Wall -O2 -fno-warn-unused-do-bind FFISo.hs cc -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 

这是字节码解释器GHCi中的dynamic链接目标文件的已知限制 。

如果加载静态链接到给定C对象的编译代码,然后也通过FFI引用某个Haskell解释为同一个C对象,则运行时链接程序将被强制加载C对象。

现在,在地址空间中有两个C符号版本,随后出现故障。

您必须在GHCi模式下解释所有内容,或者放弃在此过程中使用GHCi。 对于某些OS链接器,可以通过dynamic表( -x标志)公开静态链接的符号表。