首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用GHCi声明时的FFI运行时链接器问题

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

Stack Overflow用户
提问于 2012-05-19 02:44:59
回答 1查看 992关注 0票数 50

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

考虑FFISo.hs

代码语言:javascript
复制
{-# 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

代码语言:javascript
复制
#include <stdio.h>

void callMeFromC(void);

void callMeFromHaskell(void)
{
    printf("callMeFromHaskell\n");
    callMeFromC();
}

FFIFun/Foo.hs

代码语言:javascript
复制
{-# 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

代码语言:javascript
复制
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

所以,我现在的问题是:

代码语言:javascript
复制
$ 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系统,但都是GHC7.4.1):

代码语言:javascript
复制
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运行得很好:

代码语言:javascript
复制
$ 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
EN

回答 1

Stack Overflow用户

发布于 2013-01-16 22:20:53

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

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

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

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10658104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档