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

huangapple go评论87阅读模式
英文:

Calling c function, order of "import fmt", "import C" is causing build error, why?

问题

我有以下简单的测试Go代码: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专家们的问题:

为什么在Go中import的顺序很重要?

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

如果我再次遇到这种错误,如何进行最佳调试?

英文:

I have the following simple test go code : call_c.go

package main

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

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

I use "go build call_c.go" to build the program and that builds fine.

But I found that if I simplely reverse the order of "import fmt", "import C" or add a newline between the C /* */ block code and the first import statement, the "go build call_c.go" command will return an error:

go build call_c.go
37: error: &#39;getData&#39; undeclared (first use in this function)

Questions for expert gophers out there:

Why is the order of import important in go?

Why can't I add space between C block and the first import statement?

If I see this kind of error again, how best to debug it?

答案1

得分: 2

导入的顺序通常不重要。但是在使用cgo时,import "C"非常特殊。

根据文档

如果导入的"C"紧接着一个注释,该注释被称为前导,将在编译包的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处理,因为它没有紧接着的import "C"。(或者更确切地说,import "C"之前没有注释)

英文:

The order of import arn't generally important. But import &quot;C&quot; is very special when using cgo.

From the 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 &lt;stdio.h&gt;
// #include &lt;errno.h&gt;
import &quot;C&quot;

So, if you have a newline between your comment which contain the C code, and the import &quot;C&quot; , then the comment is just another comment, and isn't processed by cgo.

Similarly if you reverse the order of import:

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

The code in the comment is just another comment and isn't processed by cgo since it isn't immediately followed by an import "C". (or rather, import &quot;C&quot; isn't preceded by a comment)

答案2

得分: 0

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

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

英文:

It's important only because that's the way the tool is defined to work -- golang.org/cmd/cgo/

A lot of the Go tool-chain is convention based, and you need to follow the proper conventions for it to work properly.

huangapple
  • 本文由 发表于 2014年10月17日 02:09:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/26411121.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定