Haskell中通过ccall调用C函数时printf无法输出的原因是什么?
问题:为何C代码中的printf输出未出现在Haskell程序运行结果中?
Haskell代码
{-# LANGUAGE ForeignFunctionInterface #-} import GHC.Ptr import Foreign import Foreign.C import Control.Monad foreign import ccall unsafe "fibonacci.c fib" c_fib :: Int -> Int example :: IO () example = print (c_fib 5) main = example
C代码(fibonacci.c)
#include <stdio.h> int fib(const int n) { if (n == 1) { printf("here"); return 1; } else { return n*fib(n-1); } }
运行结果
120 // does not print "here"
解答
这是C标准库的输出缓冲机制导致的问题:
printf默认采用行缓冲模式,只有当输出内容包含换行符\n、缓冲区被手动刷新,或是程序正常触发缓冲区刷新逻辑时,缓冲区里的内容才会被输出到终端。- 你的代码里
printf("here")没有加换行,Haskell程序调用完C函数后直接执行print并退出,此时C的输出缓冲区还没来得及刷新,里面的"here"就随着进程结束被丢弃了。
解决办法有两种:
- 给
printf添加换行符:printf("here\n"); - 在
printf后手动刷新标准输出缓冲区:printf("here"); fflush(stdout);
另外补充:原C代码漏掉了#include <stdio.h>头文件,虽然部分编译器允许隐式声明,但规范写法必须加上,否则printf和fflush的行为可能处于未定义状态。
内容的提问来源于stack exchange,提问作者kesarling
相关产品推荐
相关产品推荐

