gpt4 book ai didi

go - 使用 cgo,为什么在 golang 输出时 C 输出的不是 'survive' 管道?

转载 作者:IT王子 更新时间:2023-10-29 01:09:12 25 4
gpt4 key购买 nike

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

我从类似于 examples I've found 的简单测试开始

    package main

import (
"fmt"
"unsafe"
)

/*
#import <stdio.h>
#import <stdlib.h>
*/
import "C"

func main() {
go2c := "Printed from C.puts"
var cstr *C.char = C.CString(go2c)
defer C.free(unsafe.Pointer(cstr))
C.puts(cstr)
fmt.Printf("Printed from golang fmt\n")
}

这个简单的示例只是通过基本的 cgo 从 golang(使用 fmt.Printf)和原始 C(使用 C.puts)将字符串回显到标准输出 绑定(bind)。

当我直接在我的终端中运行它时,我看到两行:

    $ ./main
Printed from C.puts
Printed from golang fmt

当我运行它但以任何方式重定向输出时——管道到less,shell重定向到一个文件,等等——我只看到golang的输出:

    ./main | cat
Printed from golang fmt

管道/重定向时 C.puts 内容会发生什么变化?

次要问题:这是 cgo 怪癖,还是我不知道的 c 标准库怪癖?这种行为是否记录在案?我将如何自行调试它(例如,是否有一种好的/合理的方法让我“检查”每个 block 中的 FD1 到底是什么?)

更新:如果相关,我正在使用 go version go1.6.2 darwin/amd64

最佳答案

这是您看到的 C 行为。

Go 不缓冲 stdout,而在 C 中通常是缓冲的。当 C 库检测到 stdout 是一个 tty 时,它可能会使用行缓冲,因此 puts 插入的附加 \n 将导致输出被显示。

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

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")

另见

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?

关于go - 使用 cgo,为什么在 golang 输出时 C 输出的不是 'survive' 管道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42634640/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com