2009-12-16 13 views
5

Ich entwickle ein kleines Haskell-Programm, das eine externe statische Bibliothek verwendet, die ich in C++ entwickelt habe. Es greift auf die lib über das FFI (fresh function interface) von ghc zu. Innerhalb dieser Bibliothek möchte ich etwas an die Konsole ausgeben. Allerdings sieht es für mich wie die C++ Seite der Dinge nicht ein korrektes Handle zu stdout haben, da Ausgabe nicht auf der Konsole angezeigt wird. Also, meine Fragen sind:Verwenden von stdout/stderr/stdin Streams hinter haskells FFI

  • Hat ghc kapern diese drei Ströme (stdout, stdin, stderr) oder libstdC++ einfach initialisiert sie nicht, weil ich mit ghc Verknüpfung bin?
  • Müssen meine FFI-Importe "sicher" sein, wenn sie auf stdout schreiben?
  • Wie kann ich Stdout an eine C-Funktion übergeben? Soll ich es einfach direkt weitergeben oder brauche ich einen C-Typ?

Zusätzliche Hinweise: Ich Verknüpfung libstdC++ direkt an die ausführbaren Datei (das heißt ghc -lstdC++ ...), die ich naiverweise angenommen, wäre der richtige Weg, dies zu tun. Scheint gut

Haftungsausschluss zu arbeiten: Noch ziemlich neu in Haskell, so Gehversuche für jetzt; P

Antwort

4

Ihr Problem, dass libstdc zu sein scheint ++ nicht initialisiert wird. Ich bin nicht ganz sicher, warum — -lstdc++ auf meinem System — ausreicht, aber sehen Sie, ob es anders herum funktioniert.

Main.hs:

{-# LANGUAGE ForeignFunctionInterface #-} 
module Main where 
foreign export ccall "Main_main" main :: IO() 
foreign import ccall driver_callback :: IO() 
main = putStrLn "Now in Haskell" >> driver_callback 

driver.cc:

#include <iostream> 

extern "C" { 
# include "HsFFI.h" 

# ifdef __GLASGOW_HASKELL__ 
# include "Main_stub.h" 
    extern void __stginit_Main(void); 
# endif 

    void driver_callback(void) { 
     std::cout << "Back in C++" << std::endl; 
    } 
} 

int main(int argc, char **argv) { 
    hs_init(&argc, &argv); 
# ifdef __GLASGOW_HASKELL__ 
    hs_add_root(__stginit_Main); 
# endif 

    std::cout << "Starting in C++" << std::endl; 

    Main_main(); 

    hs_exit(); 
    return 0; 
} 

Kompilieren:

 
$ ghc -c --make Main 
[1 of 1] Compiling Main    (Main.hs, Main.o) 
$ ghc --make -no-hs-main -lstdc++ Main driver.cc 
Linking Main ... 
$ ./Main 
Starting in C++ 
Now in Haskell 
Back in C++ 
+1

Es stellte sich das Problem zwischen dem Stuhl und der Tastatur war aus. Aufgrund meiner Unerfahrenheit mit Haskell machte ich einen dummen unverwandten Fehler. Ihre Antwort war sehr hilfreich, da sie mir half festzustellen, dass das stdlibC++ tatsächlich korrekt initialisiert wird und ich nur ein bisschen ein Idiot war. Aus diesem Grund bekommst du meine angenommene Antwort. Vielen Dank! –