2009-12-16 14 views
5
de Haskell

Estoy desarrollando un pequeño programa haskell que usa una biblioteca estática externa que he desarrollado en C++. Accede a la lib a través de la FFI (interfaz de función externa) de ghc. Dentro de esta biblioteca me gustaría hacer algunos resultados en la consola. Sin embargo, parece como el lado C++ de las cosas no tiene un identificador correcto para stdout porque la salida no aparece en la consola. Por esto, mis preguntas son:Uso de corrientes stdout/stderr/stdin detrás de FFI

  • ¿Se secuestran GHC estas tres corrientes (la salida estándar, la entrada estándar, stderr) o libstdC++ es simplemente no inicializar porque estoy vinculación con GHC?
  • ¿Las importaciones de mi FFI deben ser "seguras" si escriben en stdout?
  • ¿Cómo puedo pasar el stdout a una función C? ¿Debería simplemente pasarlo directamente o necesito un tipo C?

Notas adicionales: estoy vinculando libstdC++ directamente al ejecutable (es decir GHC -lstdC++ ...) que, con ingenuidad que supuse sería la forma correcta de hacer esto. Parece funcionar bien

responsabilidad: Sigue siendo bastante nuevo en Haskell, por lo que los pasos del bebé por ahora; P

Respuesta

4

Su problema parece ser que libstdC++ no está siendo inicializado. No estoy del todo seguro de por qué — -lstdc++ es suficiente en mi sistema — pero vea si funciona al revés.

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

Compilación:

 
$ 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

Resultó que el problema era entre la silla y el teclado. Hice un error sin relación tonta debido a mi inexperiencia con Haskell. Tu respuesta fue bastante útil ya que me ayudó a establecer que el stdlibC++ realmente se inicializa correctamente y que simplemente estaba siendo un poco idiota. Por esta razón, obtienes mi respuesta aceptada. ¡Gracias! –

Cuestiones relacionadas