我在Ubuntu 10.04中使用GHC 6.12.1
当我尝试将FFI语法用于静态存储时,只有以解释模式运行的模块(即GHCI)才能正常工作。编译的模块具有无效指针,并且不起作用。我想知道是否有人可以重现这个问题,这是我的代码或GHC中的错误,以及(如果是后者)这是否是一个已知问题。
我正在使用sys_siglist
,因为它存在于我系统上的标准库中,但我不相信实际使用的存储很重要(我在编写绑定到libidn时发现了这一点)。如果有帮助,则在sys_siglist
中将<signal.h>
定义为:
extern __const char *__const sys_siglist[_NSIG];
我认为这种类型可能是问题所在,所以我也尝试将它包装在一个简单的C程序中:
#include<stdio.h>
const char **test_ffi_import()
{
printf("C think sys_siglist = %X\n", sys_siglist);
return sys_siglist;
}
但是,导入不会更改结果,printf()
调用会将相同的指针值打印为show siglist_a
。
我怀疑它与静态和动态库加载有关。
更新:#haskell中有人建议这可能是64位特定的;如果有人试图重现它,你能提一下你的架构以及它是否在评论中起作用?
代码如下:
-- A.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module A where
import Foreign
import Foreign.C
foreign import ccall "&sys_siglist"
siglist_a :: Ptr CString
-
-- B.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module B where
import Foreign
import Foreign.C
foreign import ccall "&sys_siglist"
siglist_b :: Ptr CString
-
-- Main.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Foreign
import Foreign.C
import A
import B
foreign import ccall "&sys_siglist"
siglist_main :: Ptr CString
main = do
putStrLn $ "siglist_a = " ++ show siglist_a
putStrLn $ "siglist_b = " ++ show siglist_b
putStrLn $ "siglist_main = " ++ show siglist_main
peekSiglist "a " siglist_a
peekSiglist "b " siglist_b
peekSiglist "main" siglist_main
peekSiglist name siglist = do
ptr <- peekElemOff siglist 2
str <- maybePeek peekCString ptr
putStrLn $ "siglist_" ++ name ++ "[2] = " ++ show str
我希望像这样的输出,其中所有指针值都相同且有效:
$ runhaskell Main.hs
siglist_a = 0x00007f53a948fe00
siglist_b = 0x00007f53a948fe00
siglist_main = 0x00007f53a948fe00
siglist_a [2] = Just "Interrupt"
siglist_b [2] = Just "Interrupt"
siglist_main[2] = Just "Interrupt"
但是,如果我编译A.hs(使用ghc -c A.hs
),那么输出将更改为:
$ runhaskell Main.hs
siglist_a = 0x0000000040378918
siglist_b = 0x00007fe7c029ce00
siglist_main = 0x00007fe7c029ce00
siglist_a [2] = Nothing
siglist_b [2] = Just "Interrupt"
siglist_main[2] = Just "Interrupt"
答案 0 :(得分:1)
我无法在Linux x86上使用6.10.4或6.12.1重现此问题。 (请编辑您的问题以确认您在x86-64上看到的架构)
[tommd@Mavlo Test]$ ghc-6.12.1 --make irc.hs
[1 of 3] Compiling B ( B.hs, B.o )
[2 of 3] Compiling A ( A.hs, A.o )
[3 of 3] Compiling Main ( irc.hs, irc.o )
Linking irc ...
[tommd@Mavlo Test]$ ./irc
siglist_a = 0x080ab4c0
siglist_b = 0x080ab4c0
siglist_main = 0x080ab4c0
siglist_a [2] = Just "Interrupt"
siglist_b [2] = Just "Interrupt"
siglist_main[2] = Just "Interrupt"
[tommd@Mavlo Test]$ ghc-6.10.4 irc.hs --make
[1 of 3] Compiling A ( A.hs, A.o )
[2 of 3] Compiling B ( B.hs, B.o )
[3 of 3] Compiling Main ( irc.hs, irc.o )
Linking irc ...
[tommd@Mavlo Test]$ ./irc
siglist_a = 0x0809ec80
siglist_b = 0x0809ec80
siglist_main = 0x0809ec80
siglist_a [2] = Just "Interrupt"
siglist_b [2] = Just "Interrupt"
siglist_main[2] = Just "Interrupt"
答案 1 :(得分:1)
您遇到this bug。使用-fPIC
编译代码以解决问题。