CGo 不编译 C 文件
CGo doesn't compile C files
我有一个非常简单的设置:一个 .go 文件 (test.go) 和一个 .c 文件 (PMDK.c).我在 Go 中包含 .c 文件如下:
test.go:
package main
/*
#include "PMDK.c"
#cgo pkg-config: libpmem
*/
import "C"
func main() {
C.helloWorld()
}
当我 运行 go 运行 test.go 时,它只构建一次。无论我对 PMDK.c 做什么更改,我的程序每次都具有完全相同的行为。
我也尝试了 go build test.go,结果相同。
最后,在 之后,我只是 go build。这没有用,因为我必须创建一个 .mod 文件 (go build test.go)。然后,问题是 PMDK.c 中的三个函数(helloWorld 和其他两个)据说被定义了多次。
我无法让它构建我的更改。
顺便说一下,如果我 copy/move 将源文件放到另一个目录并在那里构建它们,则更改将应用(仅一次,再次)。
问题的核心是你的设置错误:你的Go代码应该#include
,在Cgo前缀中,只有headers for 任何你想单独编译的 C 代码。例如:
package main
/*
#include "pmdk.h"
*/
import "C"
func main() {
C.helloWorld()
}
你可以将C代码放入前缀:
package main
/*
#include <stdio.h>
void helloWorld() {
printf("hello world from C\n");
}
*/
import "C"
...
但是如果你把你的 C 代码放到一个单独的文件(prog.c
,等等),你应该创建一个小的header file 简单地声明了每个函数,#include
来自 C 代码和 Go 代码的 header 文件。1
运行:
go build
如果 C 代码发生变化,将编译它,如果发生变化,将构建 Go 代码,并且 link 将两者适当地结合在一起。如果您 #include
将 C 代码直接放入 Go 包中,就像您所做的那样,go build
将同时构建 C 代码 和 构建 Go 代码 ,其中包括 C 代码,这就是您得到重复定义的原因。
无论您在 Cgo header 中嵌入什么 C 代码,都不应出现在其他地方。这是放置小型“管道适配器”的好地方,如果您有一些现有的 C 代码主要适用于 Go,但需要一些调整。
1这是 C 中的通用技术,用于确保 header 文件 声明 函数与相同函数的 C 源代码定义。也就是说,header fifth.h
可能会说:
void func(int arg1, char *arg2);
另外,C 代码将显示为:
#include "fifth.h"
void func(int zorg, char *evil) {
// ...
}
C 编译器将检查声明是否与定义匹配。
我有一个非常简单的设置:一个 .go 文件 (test.go) 和一个 .c 文件 (PMDK.c).我在 Go 中包含 .c 文件如下:
test.go:
package main
/*
#include "PMDK.c"
#cgo pkg-config: libpmem
*/
import "C"
func main() {
C.helloWorld()
}
当我 运行 go 运行 test.go 时,它只构建一次。无论我对 PMDK.c 做什么更改,我的程序每次都具有完全相同的行为。
我也尝试了 go build test.go,结果相同。
最后,在
问题的核心是你的设置错误:你的Go代码应该#include
,在Cgo前缀中,只有headers for 任何你想单独编译的 C 代码。例如:
package main
/*
#include "pmdk.h"
*/
import "C"
func main() {
C.helloWorld()
}
你可以将C代码放入前缀:
package main
/*
#include <stdio.h>
void helloWorld() {
printf("hello world from C\n");
}
*/
import "C"
...
但是如果你把你的 C 代码放到一个单独的文件(prog.c
,等等),你应该创建一个小的header file 简单地声明了每个函数,#include
来自 C 代码和 Go 代码的 header 文件。1
运行:
go build
如果 C 代码发生变化,将编译它,如果发生变化,将构建 Go 代码,并且 link 将两者适当地结合在一起。如果您 #include
将 C 代码直接放入 Go 包中,就像您所做的那样,go build
将同时构建 C 代码 和 构建 Go 代码 ,其中包括 C 代码,这就是您得到重复定义的原因。
无论您在 Cgo header 中嵌入什么 C 代码,都不应出现在其他地方。这是放置小型“管道适配器”的好地方,如果您有一些现有的 C 代码主要适用于 Go,但需要一些调整。
1这是 C 中的通用技术,用于确保 header 文件 声明 函数与相同函数的 C 源代码定义。也就是说,header fifth.h
可能会说:
void func(int arg1, char *arg2);
另外,C 代码将显示为:
#include "fifth.h"
void func(int zorg, char *evil) {
// ...
}
C 编译器将检查声明是否与定义匹配。