你使用的是什么版本的Go(Go版本)?
$ go version
go version go1.20.2 linux/amd64
项目结构:
Directory structure --
example --> main.go
-->lib
lib.c
lib.h
main.go
package main
// #include "lib/lib.h"
// #include <stdio.h>
// #include <stdlib.h>
import "C"
import (
"fmt"
"unsafe"
)
func main() {
cstrin := C.CString("welcome")
s1 := C.struct_s1{b: cstrin, a: 100}
C.f32_123(&s1)
cs := C.GoString(s1.b)
fmt.Println(cs)
fmt.Println(s1)
C.free(unsafe.Pointer(cstrin))
}
lib/lib.c
#include <stdlib.h>
#include <stdio.h>
void printc(char *str, int *t)
{
str = "Test";
printf("%d\n", *t);
*t = 30;
printf("%s\n", str);
}
void f32_123(struct s1 *s)
{
printf("%s\n", s->b);
s->a = 10;
s->b = "Hello123";
printf("%d\n", s->a);
printf("%s\n", s->b);
}
lib/lib.h
struct s1 {
int a;
char *b;
};
void printc(char *str, int *t);
void f32_123(struct s1 *s);
编译时出错
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-3024881602/000001.o: in function _cgo_cf24297edd23_Cfunc_f32_123': /tmp/go-build/cgo-gcc-prolog:49: undefined reference to f32_123'
collect2: error: ld returned 1 exit status
我希望代码能够成功编译,但不知何故却没有。如果我正确阅读了文档,那么我必须将lib.c
和lib.h
与main.go
文件保存在同一个目录中。但我不确定是否可以实现这一点,或者我做错了什么。
- 如果我把所有的文件都放在同一个目录下,那么编译就成功了。
- 如果我将
lib.c
和lib.h
保存在子目录中,则编译失败 - 如果我从main.go中删除一个函数
f32_123
,那么编译也会成功,这很奇怪,这就是打开这个bug的原因,以便更多地了解为什么当lib.h
和lib.c
在subdir中时,编译不会出现printc函数的问题。
1条答案
按热度按时间k3bvogb11#
首先,@JimB给出了这个公认的答案:https://stackoverflow.com/a/28881331/5739452表示在子目录中构建对象或库不是
go build
可以做的事情。假设你有这样的结构:
以下是一些简单的文件,以保持清晰:
所以,如果你有一个像这样的
main.go
,你可以从go build main.go
构建所有的东西:这是可行的,因为我们实际上
#include
库的“C”源代码(它隐式地导入lib/lib.h
文件)。但是,对于更复杂的库,您可能需要将其构建为一个单独的,更正常的C工具链,预工作构建步骤:
然后使用另一个Go文件:
main2.go
: