使用cgo,为什么C输出在golang的时候没有“存活”管道?

时间:2017-03-06 20:08:46

标签: go cgo

我正在尝试使用cgo来使用golang的C代码,但是在我的小小的世界测试中,我遇到了一些我无法理解的东西或者找到了更多关于它的信息。 我开始的是一个类似于我发现的例子的简单测试     包主     进口(         “FMT”         “不安全”     )     / *     #import< stdio.h>     #import< stdlib.h>     * /     导入“C”     func main(){         go2c:=“从C.puts打印”         var cstr * C.char = C.CString(go2c)         推迟C.free(unsafe.Pointer(cstr))         C.puts(CSTR)         fmt.Printf(“从golang fmt打印\ n”)     } 这个简单的例子只是通过基本的cgo绑定从golang(使用fmt.Printf)和raw C(使用C.puts)回调字符串到stdout。 当我直接在终端中运行时,我看到两行:     $ ./main     从C.puts打印     来自golang fmt的印刷品 当我运行它但以任何方式重定向输出 - 管道到更少,shell重定向到文件等 - 我只看到golang的输出:     ./main |猫     来自golang fmt的印刷品 管道/重定向时,C.puts内容会发生什么变化? 次要问题:这是一个cgo怪癖,还是一个我不知道的标准库怪癖?这种行为是否有记录?我将如何自行调试(例如,我是否有一个好的/合理的方式'检查'每个块中的FD1究竟是什么?) 更新:如果相关,我正在使用go版本go1.6.2 darwin / amd64。

2 个答案:

答案 0 :(得分:2)

这是你看到的C行为。

Go不缓冲 do { printf("What is your name?\n"); char str[] = get_string(); 'error: array initializer must be an initializer list or string literal' } while (namelen[i] = int); //error: use of undeclared identifier 'namelen' char str[49] = namelen; //error: use of undeclared identifier'namelen' ,而在C中它通常是缓冲的。当C库检测到stdout是tty时,它可能使用行缓冲,因此stdout插入的附加\n将导致输出显示。

您需要刷新puts以确保获得所有输出:

stdout

另见

Why does printf not flush after the call unless a newline is in the format string?

Is stdout line buffered, unbuffered or indeterminate by default?

答案 1 :(得分:0)

C库缓冲是每行,因此第一行可以在正确刷新之前保留在缓冲区中(在C程序的退出时间完成)。您可以尝试刷新标准输出,也可以尝试在第一个字符串中添加尾随\ n。如果添加\ n,它是否有效?