使用cgo,为什么C输出不';生存';戈朗'时的管道;是吗?
我正在尝试使用cgo来使用golang的C代码,但在我的hello world小测试中,我遇到了一些我无法理解或无法找到更多信息的问题 我从一个简单的测试开始,类似于 当我运行此命令,但以任何方式将输出重定向到使用cgo,为什么C输出不';生存';戈朗'时的管道;是吗?,go,cgo,Go,Cgo,我正在尝试使用cgo来使用golang的C代码,但在我的hello world小测试中,我遇到了一些我无法理解或无法找到更多信息的问题 我从一个简单的测试开始,类似于 当我运行此命令,但以任何方式将输出重定向到less、shell重定向到文件等时,我只看到golang的输出: ./main | cat Printed from golang fmt 管道/重定向时,C.put内容会发生什么变化 次要问题:这是cgo的怪癖,还是我不知道的c标准库的怪癖?这种行为有记录吗?我将如何
less
、shell重定向到文件等时,我只看到golang的输出:
./main | cat
Printed from golang fmt
管道/重定向时,C.put
内容会发生什么变化
次要问题:这是cgo的怪癖,还是我不知道的c标准库的怪癖?这种行为有记录吗?我将如何自己调试它(例如,是否有一种好的/合理的方法让我“检查”每个块中的FD1到底是什么?)
更新:如果相关的话,我使用的是
go版本go1.6.2 darwin/amd64
C库缓冲是每行的,因此第一行可以在正确刷新之前留在缓冲区中(在C程序退出时完成)。您可以尝试刷新标准输出,也可以尝试在第一个字符串中添加尾随\n。如果您添加了\n 这是你看到的C行为
Go不缓冲标准输出,而在C中它通常是缓冲的。当C库检测到stdout
是tty时,它可能会使用行缓冲,因此由put
插入的附加\n
将导致显示输出
您需要刷新标准输出以确保获得所有输出:
go2c := "Printed from C.puts"
var cstr *C.char = C.CString(go2c)
defer C.free(unsafe.Pointer(cstr))
C.puts(cstr)
C.fflush(C.stdout)
fmt.Printf("Printed from golang fmt\n")
另见
哈,我刚发帖就发现了这一点,我正要回答自己,但你先到了这里!否:添加新行没有任何区别(
put
无论如何都会添加一行)。然而:是的:刷新stdout会有所不同:C.fflush(C.stdout)
在相关的点上是有效的谢谢——我在发布之后偶然发现需要刷新:-)。我不完全理解为什么在这种情况下,与“正常”c相比,c是缓冲的:如果我直接编写等价的hello world c程序,使用puts
,并重定向它,我会看到预期的输出。在这种情况下,是我的C编译器为我添加了刷新还是什么;C通常会在终止时刷新,但cgo不会调用C的atexit
callbacks–这个问题表明这是故意的,但让它变得模棱两可。很明显是这样,但我找不到这样的讨论<代码>fflush就是这样@奥尔斯:是的,这很有道理。我一直认为,如果您需要确保数据已写入,请调用fflush。
./main | cat
Printed from golang fmt
go2c := "Printed from C.puts"
var cstr *C.char = C.CString(go2c)
defer C.free(unsafe.Pointer(cstr))
C.puts(cstr)
C.fflush(C.stdout)
fmt.Printf("Printed from golang fmt\n")