2009-12-16 8 views
5

Sto sviluppando un piccolo programma haskell che utilizza una libreria statica esterna che ho sviluppato in C++. Accede alla lib attraverso FFI di ghc (interfaccia di funzione straniera). All'interno di questa libreria mi piacerebbe fare un po 'di output sulla console. Tuttavia, è come come il lato C++ delle cose non ha un handle corretto per lo stdout perché l'output non appare sulla console. Allora, le mie domande sono:Utilizzo di stdout/stderr/stdin streams dietro l'FFI di haskell

  • Vuol ghc dirottare questi tre flussi (stdout, stdin, stderr) o è libstdC++ semplicemente non l'inizializzazione perché sto collegando con GHC?
  • Le mie importazioni FFI devono essere "sicure" se scrivono su stdout?
  • Come posso passare lo stdout a una funzione C? Dovrei semplicemente passarlo direttamente o ho bisogno di un tipo C?

Note aggiuntive: sto collegando libstdC++ direttamente all'eseguibile (vale a dire GHC -lstdC++ ...) che ho ingenuamente pensato sarebbe il modo corretto di fare questo. Sembra funzionare bene

responsabilità: ancora abbastanza nuovo per Haskell, così piccoli passi per ora; P

risposta

4

Il tuo problema sembra essere che libstdC++ non viene inizializzato. Non sono del tutto sicuro del motivo per cui — -lstdc++ è sufficiente sul mio sistema — ma vediamo se funziona il contrario.

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

Compilazione:

 
$ 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

Si è scoperto che il problema era tra la sedia e la tastiera. Ho fatto uno stupido errore non correlato a causa della mia inesperienza con Haskell. La tua risposta è stata molto utile in quanto mi ha aiutato a stabilire che lo stdlibC++ in realtà si inizializza correttamente e io stavo semplicemente diventando un idiota. Per questo motivo ottieni la mia risposta accettata. Grazie! –