0

我有以下简单的测试代码: 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 /* */块代码和第一个import语句之间添加一个换行符,“go build call_c.go”命令就会返回一个错误:

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

专家地鼠的问题:

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

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

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

4

2 回答 2

2

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

文档

如果“C”的导入紧跟在注释之前,则该注释称为前导,在编译包的 C 部分时用作标头。例如:

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

因此,如果在包含 C 代码import "C"的注释与

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

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

注释中的代码只是另一个注释,并没有被 cgo 处理,因为它没有紧跟 import "C"。(或者更确切地说,import "C"前面没有评论)

于 2014-10-16T18:18:55.347 回答
0

这很重要,因为这是定义工具工作的方式——golang.org/cmd/cgo/

许多 Go 工具链都是基于约定的,您需要遵循适当的约定才能使其正常工作。

于 2014-10-16T18:16:00.330 回答