在haskell的FFI后面使用stdout / stderr / stdin流

时间:2009-12-16 21:31:43

标签: c++ haskell io ghc ffi

我正在开发一个小的haskell程序,它使用我用C ++开发的外部静态库。它通过ghc的FFI(外部函数接口)访问lib。在这个库里面我想对控制台做一些输出。但是,它看起来对我来说就像c ++方面的东西没有正确的stdout句柄,因为输出没有出现在控制台上。那么,我的问题是:

  • ghc是否劫持了这三个流(stdout,stdin,stderr)或libstdc ++只是没有初始化它们因为我正在与ghc链接?
  • 如果写入stdout,我的FFI导入是否需要“安全”?
  • 如何将stdout传递给C函数?我应该直接传递它还是需要C型?

附加说明:我将libstdc ++直接链接到可执行文件(即ghc -lstdc ++ ...),我天真地认为这是正确的方法。似乎运作良好

免责声明:对于Haskell来说还是一个新手,所以宝贝现在迈出了步伐; P

1 个答案:

答案 0 :(得分:4)

你的问题确实似乎没有初始化libstdc ++。我不完全确定为什么 - -lstdc++对我的系统来说已经足够了 - 但看看它是否相反。

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

编译:

$ 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++