go - 调用 c 函数, "import fmt"的顺序, "import C"导致构建错误,为什么?

标签 go cgo

我有以下简单的测试代码:call_c.go

package main

/*
int getData(int *p, int n )
{
     int i; 
     for(i=0;i<n;i++) {
        p[i]=i;
    } 
    return n;
}
*/
import "C"
import "fmt"

func main() {
    var a [5]int32
    i := C.getData((*C.int)(&a[0]), 5)
    fmt.Println(i, a)
}

我使用“go build call_c.go”来构建程序并且构建良好。

但是我发现,如果我简单地颠倒“import fmt”、“import C”的顺序或者在C/* */ block 代码和第一个import语句之间添加一个换行符,“go build call_c.go”命令将返回一个错误:

go build call_c.go
37: error: 'getData' undeclared (first use in this function)

专家 gophers 的问题:

为什么导入顺序在 go 中很重要?

为什么我不能在 C block 和第一个 import 语句之间添加空格?

如果我再次看到这种错误,如何最好地调试它?

最佳答案

导入的顺序通常并不重要。但是import "C"在使用cgo的时候很特别。

来自docs :

If the import of "C" is immediately preceded by a comment, that comment, called the preamble, is used as a header when compiling the C parts of the package. For example:

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

因此,如果您在包含 C 代码的注释和 import "C" 之间有一个换行符,那么该注释只是另一个注释,不会被 cgo 处理。

同样,如果您颠倒导入顺序:

/*
int getData(int *p, int n )
{
     int i; 
     for(i=0;i<n;i++) {
        p[i]=i;
    } 
    return n;
}
*/
import "fmt"
import "C"

注释中的代码只是另一个注释,不会被 cgo 处理,因为它后面没有紧跟导入“C”。 (或者更确切地说,import "C" 前面没有注释)

关于go - 调用 c 函数, "import fmt"的顺序, "import C"导致构建错误,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26411121/

相关文章:

go - 有没有办法在go中读取服务器应用程序内部的IP连接头?

pointers - 将 *os.File 作为 *io.Reader 传递

c - 为什么我用cgo的时候报错 "undefined reference to ` add2”

go - 正确的 Go 类型传递给 C 函数?

mongodb - 如何防止 mgo 将 int 解码为 float64

google-app-engine - Appengine 搜索索引和命名空间

go - 为什么我的交叉编译的 CGO 二进制文件不能在 Raspberry Pi (Raspbian) 上运行?

c++ - 在 macOS 主机上为 Windows 目标交叉编译 golang 和 cgo

go - 使用 dep 运行 go vet 时找不到头文件

Golang 字符串结束字符