2010-05-01 20 views
2

J'utilise GHC 6.12.1, dans Ubuntu 10.04bibliothèques Compilé Haskell avec les importations IFF ne sont pas valides lorsqu'ils sont importés dans GHCi

Lorsque je tente d'utiliser la syntaxe pour le stockage statique IFF, seuls les modules en cours d'exécution en mode interprété (c.-à- GHCI) fonctionnent correctement. Les modules compilés ont des pointeurs non valides et ne fonctionnent pas. Je voudrais savoir si quelqu'un peut reproduire le problème, que ce soit une erreur dans mon code ou GHC, et (si ce dernier) si c'est un problème connu. J'utilise sys_siglist parce qu'il est présent dans une bibliothèque standard sur mon système, mais je ne crois pas que le stockage réel utilisé soit important (je l'ai découvert en écrivant une liaison à libidn). Si elle aide, sys_siglist est défini dans <signal.h> comme:

extern __const char *__const sys_siglist[_NSIG]; 

Je pensais que ce type pourrait être le problème, alors je l'ai aussi essayé envelopper dans une procédure C simple:

#include<stdio.h> 
const char **test_ffi_import() 
{ 
    printf("C think sys_siglist = %X\n", sys_siglist); 
    return sys_siglist; 
} 

Cependant, l'importation que ne change pas le résultat et l'appel printf() imprime la même valeur de pointeur que show siglist_a. Je soupçonne que cela a quelque chose à voir avec le chargement de bibliothèques statiques et dynamiques. Mise à jour: quelqu'un dans #haskell a suggéré que cela pourrait être spécifique à 64 bits; Si quelqu'un essaie de le reproduire, pouvez-vous mentionner votre architecture et si cela a fonctionné dans un commentaire?

Code comme suit:

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

Je me attends quelque chose comme cette sortie, où toutes les valeurs de pointeur identiques et valides:

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

Cependant, si je compile A.hs (avec ghc -c A.hs), les changements de sortie à:

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

Répondre

1

Vous rencontrez this bug. Compilez votre code avec -fPIC pour contourner le problème.

1

je ne peux pas reproduire ce soit avec 6.10.4 ou 6.12.1 sur Linux x86. (S'il vous plaît modifier votre question pour confirmer l'architecture que vous voyez tout ceci est x86-64)

[[email protected] 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 ... 
[[email protected] 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" 
[[email protected] 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 ... 
[[email protected] 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" 
+0

Si * tout * du code est compilé, cela fonctionne également sur mon système; l'erreur se produit uniquement lorsqu'un module compilé est chargé dans GHCI. –

+0

Ouais, ça marche bien pour moi aussi. –