无法打印到标准输出
Unable to print to stdout
我能够让程序 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))
}
它运行无误,但不打印任何内容。上面的代码片段主要基于 "Strings and things" 代码 here.
试试这个:
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
方法将一个字符串写入数据流,在您的例子中是 stdout,它指向一个指向不存在的文件的指针,因为它之前既没有打开也没有在任何地方定义。因此,即使程序看起来执行无误,您也看不到任何标准输出,因为它被重定向到一个不存在的文件。
此外,应该注意的是,简单地将 Strings and things 部分的代码直接放到主程序中而不进行一些定制是行不通的,因为它在博客中作为一个包提供,这就是为什么有对现有文件的困惑。博客 post 中的 print
包似乎只是假设您尝试写入数据流的文件之前已经在某处定义。这有点令人困惑,他们可能应该对此进行调整。
我用 puts
替换了 fputs
并删除了指向文件的指针,程序执行得很好。
希望即使进行了修改,这也有助于实现您正在寻找的目标!
另一个原因可能是因为你有 C 标准库 链接到你的 Go 程序,但是 "standard I/O streams" (以 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*
对象超出 OS 级别
已打开文件的文件描述符,
Fd()
函数从 Go 的 *os.File
.
中提取出来
我能够让程序 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))
}
它运行无误,但不打印任何内容。上面的代码片段主要基于 "Strings and things" 代码 here.
试试这个:
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
方法将一个字符串写入数据流,在您的例子中是 stdout,它指向一个指向不存在的文件的指针,因为它之前既没有打开也没有在任何地方定义。因此,即使程序看起来执行无误,您也看不到任何标准输出,因为它被重定向到一个不存在的文件。
此外,应该注意的是,简单地将 Strings and things 部分的代码直接放到主程序中而不进行一些定制是行不通的,因为它在博客中作为一个包提供,这就是为什么有对现有文件的困惑。博客 post 中的 print
包似乎只是假设您尝试写入数据流的文件之前已经在某处定义。这有点令人困惑,他们可能应该对此进行调整。
我用 puts
替换了 fputs
并删除了指向文件的指针,程序执行得很好。
希望即使进行了修改,这也有助于实现您正在寻找的目标!
另一个原因可能是因为你有 C 标准库 链接到你的 Go 程序,但是 "standard I/O streams" (以 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*
对象超出 OS 级别
已打开文件的文件描述符,
Fd()
函数从 Go 的 *os.File
.