Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用cgo,为什么C输出不';生存';戈朗'时的管道;是吗?_Go_Cgo - Fatal编程技术网

使用cgo,为什么C输出不';生存';戈朗'时的管道;是吗?

使用cgo,为什么C输出不';生存';戈朗'时的管道;是吗?,go,cgo,Go,Cgo,我正在尝试使用cgo来使用golang的C代码,但在我的hello world小测试中,我遇到了一些我无法理解或无法找到更多信息的问题 我从一个简单的测试开始,类似于 当我运行此命令,但以任何方式将输出重定向到less、shell重定向到文件等时,我只看到golang的输出: ./main | cat Printed from golang fmt 管道/重定向时,C.put内容会发生什么变化 次要问题:这是cgo的怪癖,还是我不知道的c标准库的怪癖?这种行为有记录吗?我将如何

我正在尝试使用cgo来使用golang的C代码,但在我的hello world小测试中,我遇到了一些我无法理解或无法找到更多信息的问题

我从一个简单的测试开始,类似于

当我运行此命令,但以任何方式将输出重定向到
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")