2009-12-16 7 views
5

Je développe un petit programme haskell qui utilise une bibliothèque statique externe que j'ai développée en C++. Il accède à la lib via FFI de ghc (interface de fonction étrangère). A l'intérieur de cette bibliothèque je voudrais faire une sortie à la console. Cependant, il me semble comme le côté C++ des choses n'a pas un handle correct à stdout, car la sortie n'apparaît pas sur la console. Alors, mes questions sont les suivantes:Utilisation des flux stdout/stderr/stdin derrière FFI de haskell

  • Est-ce que ces trois GHC détournent les flux (stdout, stdin, stderr) ou est libstdC++ tout simplement pas les initialiser parce que je suis la liaison avec GHC?
  • Mes importations FFI doivent-elles être "sûres" si elles écrivent sur stdout?
  • Comment puis-je transmettre stdout à une fonction C? Dois-je simplement le passer directement ou ai-je besoin d'un type C?

Notes complémentaires: Je relie libstdC++ directement à l'exécutable (à savoir GHC -lstdC++ ...) que je supposais naïvement serait la bonne façon de le faire. Semble bien fonctionner

Avertissement: encore assez nouveau pour Haskell, donc pas de bébé pour l'instant; P

Répondre

4

Votre problème ne semble être que libstdC++ ne sont pas en cours d'initialisation. Je ne suis pas tout à fait sûr pourquoi — -lstdc++ est suffisante sur mon système — mais voir si cela fonctionne dans l'autre sens.

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

Compiler:

 
$ 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

Il est avéré que le problème était entre la chaise et le clavier. J'ai fait une erreur stupide sans rapport avec mon inexpérience avec Haskell. Votre réponse a été très utile car elle m'a aidé à établir que le stdlibC++ s'initialise correctement et que j'étais simplement un peu un crétin. Pour cette raison, vous obtenez ma réponse acceptée. Merci! –

Questions connexes