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

时间:2014-10-16 18:09:20

标签: 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)
}

我使用&#34; go build call_c.go &#34;建立程序,并建立良好。

但我发现如果我简单地颠倒&#34;导入fmt&#34;,&#34;导入C&#34;或者在C / * * / block代码和第一个import语句之间添加换行符,&#34; go build call_c.go&#34;命令将返回错误:

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

专家的问题在那里:

为什么导入顺序很重要?

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

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

2 个答案:

答案 0 :(得分:2)

进口的顺序通常很重要。但是使用cgo时import "C"非常特殊。

来自docs

  

如果导入&#34; C&#34;之后会立即发表评论   注释,称为前导码,在编译C时用作标题   包的一部分。例如:

// #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处理,因为它不会立即导入&#34; C&#34;。 (或者更确切地说,import "C"之前没有评论)

答案 1 :(得分:0)

这一点非常重要,因为这是工具定义工作的方式 - golang.org/cmd/cgo/

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