Verwenden von Stdout/Stderr/Stdin -Streams hinter Haskells FFI
Frage
Ich entwickle ein kleines Haskell -Programm, das eine externe statische Bibliothek verwendet, die ich in C ++ entwickelt habe. Es greift über das FFI von GHC (Fremdenfunktionsschnittstelle) auf die LIB zu. In dieser Bibliothek möchte ich die Konsole ausgeben. Wie auch immer, es sieht aus Für mich hat die C ++ - Seite der Dinge keinen korrekten Griff für STDOut, da die Ausgabe nicht auf der Konsole erscheint. Also sind meine Fragen:
- Entführt GHC diese drei Streams (stdout, stdin, stderr) oder ist libstdc ++ sie einfach nicht initialisiert, weil ich mit GHC verlinke?
- Müssen meine FFI -Importe "sicher" sein, wenn sie an stdout schreiben?
- Wie kann ich Stdout an eine C -Funktion übergeben? Soll ich es einfach direkt bestehen oder brauche ich einen C -Typ?
Zusätzliche Bemerkungen: Ich verlinke libstdc ++ direkt mit der ausführbaren Datei (dh GHC -LSTDC ++ ...), von der ich angenommen habe, dass sie dies korrekt angenommen hat. Scheint gut zu funktionieren
Haftungsausschluss: Immer noch ziemlich neu in Haskell, also tritt Baby vorerst; P.
Lösung
Ihr Problem scheint zu sein, dass libstdc ++ nicht initialisiert wird. Ich bin mir nicht ganz sicher, warum - -lstdc++
ist ausreichend in meinem System - aber sehen Sie, ob es umgekehrt 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;
}
Kompilien:
$ 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++