【问题标题】:Unable to print to stdout无法打印到标准输出
【发布时间】:2018-12-25 22:59:05
【问题描述】:

我可以让程序 here 按预期打印 42。

但我无法将以下程序打印到标准输出:

package main

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

import (
    "unsafe"
)

func main() {
    cs := C.CString("hello")
    defer C.free(unsafe.Pointer(cs))
    C.fputs(cs, (*C.FILE)(C.stdout))
}

它运行没有错误,但它不打印任何东西。上面的 sn-p 主要是基于“Strings and things”代码here

【问题讨论】:

  • 为什么不检查C.fputs的返回值呢?它可能很好地暗示了问题。
  • 感谢:./main.go:15: cannot convert nil to type _Ctype_int
  • 你的意思是你正在做类似if C.fputs(...) != nil的事情?然后是的,C 的 fputs 显然不会返回 nil,因为 C 对 Go 风格的错误处理一无所知。 C 的 fputs 返回 int。请阅读fputs上的手册页。

标签: macos go macos-high-sierra cgo


【解决方案1】:

试试这个:

package main

// #include <stdlib.h>
// #include <stdio.h>
import "C"
import "unsafe"

func main() {
    cs := C.CString("hello")
    defer C.free(unsafe.Pointer(cs))
    C.puts(cs)
}

解释:

fputs 方法将一个字符串写入数据流,在您的例子中是标准输出,它指向一个指向不存在的文件的指针,因为该文件之前既没有打开也没有定义过。因此,即使程序似乎执行没有错误,您也看不到任何标准输出,因为它被重定向到不存在的文件。

此外,应该注意的是,简单地将代码从Strings and things 部分放到主程序中而不进行一些自定义是行不通的,因为它在博客中作为一个包提供,这就是文件混淆的原因现存的。似乎博客文章中的print 包只是假设您尝试将数据流写入其中的文件已经在之前的某个地方定义过。这有点令人困惑,他们可能应该调整一下。

我用puts 替换了fputs,并删除了指向文件的指针,程序执行得很好。

希望即使进行了修改,这也有助于实现您正在寻找的东西!

【讨论】:

  • 我不确定您的推理是否正确但接受,因为代码有效。
  • 这是隐藏问题而不是解决问题。
  • 感谢您的建设性批评帮助我学习,并随时投反对票,但我只是试图解释为什么正在尝试的代码不起作用并提供示例这仍然完成了 OP 正在寻找的东西,而不会太细化。
  • @waymobetta 那么你解释了为什么(*C.FILE)(C.stdout) 部分不起作用?
  • @leafbebop 公平,我在第一行中提到了标准输出如何被重定向到文件[不存在]。我本可以更深入地解释他尝试了什么以及为什么它不起作用。我会编辑我的帖子。
【解决方案2】:

另一个原因可能是因为您将 C标准库 与 Go 程序链接,但“标准 I/O 流”(FILE* 的形式)是C 运行时的属性,,它们必须在使用前进行初始化。

对于用 C 编写的典型程序,编译器会创建一个特殊的序言代码,该代码实际上在 C 的 main() 之前运行(通常为此它链接到目标平台的小目标文件标准,该标准执行必要的工作,然后跳转到main)。

假设在 Go 程序中不会发生这种初始化,因此这些标准 I/O 流的高级包装器会留下 未初始化。

您可以通过尝试以下方法来检查这是否属实:

f = fdopen(C.int(os.Stdout.Fd()), C.CString("w"))
C.fputs(cs, f)

看看它是否有效。

fdopen(3) 在操作系统级别创建了一个 FILE* 对象 已打开文件的文件描述符, 而Fd() 函数将其从 Go 的 *os.File 中提取出来。

【讨论】:

    猜你喜欢
    • 2013-05-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 2014-07-22
    相关资源
    最近更新 更多