英文:
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<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)
}
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: 'getData' 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 "C"
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 <stdio.h>
// #include <errno.h>
import "C"
So, if you have a newline between your comment which contain the C code, and the import "C"
, 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<n;i++) {
p[i]=i;
}
return n;
}
*/
import "fmt"
import "C"
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 "C"
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论