Tôi gặp sự cố liên quan đến FFI trong Haskell và chế độ tương tác của GHC again.Vấn đề liên kết thời gian chạy GHCi khi sử dụng khai báo FFI
Cân nhắc 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"
và 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
bạn cũng tìm thấy nó here as a gist.
Vì vậy, vấn đề của tôi bây giờ là:
$ 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, những gì là sai ở đây? Điều thú vị là tôi nhận được một lỗi khác nhau trên i686
(ở trên, đó là một hệ thống x86_64
, nhưng cả hai 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.
Ngoài ra, có một số tài liệu về nó? Tôi cảm thấy mình là người duy nhất gặp khó khăn với FFI và GHCi.
chỉnh sửa: lưu ý, rằng make test
hoạt động tốt:
$ 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
Bạn có thể gặp phải các tình huống nếu bạn cố gắng liên kết tĩnh một mô-đun với một biểu tượng FFI; và cũng tự động tải nó. –
bạn có thể xây dựng? hoặc làm cách nào để giải quyết vấn đề này? –
Tôi chơi xung quanh với nó một chút và nó có vẻ là một lỗi trong GHCi. Biểu tượng được xem xét hai lần: Một lần vì nó được tải trên dòng lệnh thông qua tệp .o và một lần vì tệp .hs được tải. Dường như. Có lẽ nó không nên liên kết ở tất cả khi bắt đầu ghci, nhưng chỉ khi thực hiện các công cụ? –