gpt4 book ai didi

haskell - 使用 FFI 声明时的 GHCi 运行时链接器问题

转载 作者:行者123 更新时间:2023-12-02 06:53:06 25 4
gpt4 key购买 nike

我对 Haskell 中的 FFI 和 GHC 的交互模式有疑问 again .

考虑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 ()

抄送:

#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 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

你也发现了here as a gist .

所以,我现在的问题是:

$ 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 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

最佳答案

这是a known limitation字节码解释器 GHCi 中的动态链接目标文件。

如果您加载针对给定 C 对象静态链接的编译代码,然后还动态解释一些也通过 FFI 引用同一个 C 对象的 Haskell,则运行时链接器将被迫加载 C 对象动态地。

现在您的地址空间中有两个版本的 C 符号,并且随之而来的是失败。

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

关于haskell - 使用 FFI 声明时的 GHCi 运行时链接器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10658104/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com