Скомпилированные библиотеки Haskell с импортом FFI недействительны при импорте в GHCI
Вопрос
Я использую GHC 6.12.1, в Ubuntu 10.04
Когда я пытаюсь использовать синтаксис FFI для статического хранения, только модули, работающие в интерпретированном режиме (то есть GHCI), работают должным образом. Скомпилированные модули имеют недопустимые указатели и не работают. Я хотел бы знать, может ли кто -нибудь воспроизвести проблему, будь то ошибка в моем коде или GHC, и (если последнее), является ли это известной проблемой.
я использую sys_siglist
Потому что он присутствует в стандартной библиотеке в моей системе, но я не верю, что фактическое хранилище использовалось (я обнаружил это, когда написал обязательство с Либидном). Если это помогает, 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"
Решение
Вы встречаетесь эта ошибка. Анкет Скомпилируйте свой код с -fPIC
Чтобы обходной, это.
Другие советы
Я не могу воспроизвести это ни с 6.10.4, ни 6.12.1 на Linux x86. (Пожалуйста, отредактируйте свой вопрос, чтобы подтвердить архитектуру, на которой вы видите,-это 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"