
php小编百草在编写代码时,经常会遇到一些问题和挑战。其中一个常见的问题是在使用cgo编译时遇到错误信息"无法用cgo编译"。这个问题可能由于各种原因引起,例如缺少依赖库、环境配置不正确等。解决这个问题需要仔细检查代码和环境,并根据具体情况进行相应的调整和修复。在本文中,我们将分享一些解决这个问题的方法和技巧,帮助大家克服这个困扰。
您使用的 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 保留到子目录中,则编译失败
PHP5学习对象教程由美国人古曼兹、贝肯、瑞桑斯编著,简张桂翻译,电子工业出版社于2007年12月1日出版的关于PHP5应用程序的技术类图书。该书全面介绍了PHP 5中的新功能、编程方法及设计模式,还分析阐述了PHP 5中新的数据库连接处理、错误处理和XML处理等机制,帮助读者系统了解、熟练掌握和高效应用PHP。
291
如果我从 main.go 中删除一个函数 f32_123 ,那么编译也会成功,这很奇怪,这就是打开此错误的原因,以更好地理解为什么在 lib.h 时编译不会出现 printc 函数问题并且 lib.c 位于子目录中。
首先,@jimb 不久前给出了这个已接受的答案:https://www.php.cn/link/50c57f7019bb52cfbebdfe5bdc42b422 a> 表示在子目录中构建对象或库不是 go build 可以做的事情。
鉴于此,假设您具有以下结构:
lib/ lib/lib.c lib/lib.h main.go
以下是一些更简单的文件,可以让事情变得清晰:
/* lib/lib.h */
struct foo {
int x;
};
void show(struct foo *arg);
/* lib/lib.c */
#include <stdio.h>
#include "lib.h"
void show(struct foo *arg) {
printf("[%d]\n", arg->x);
}
因此,如果您有这样的 main.go ,则可以从 go build main.go 构建所有内容:
package main
// #cgo cflags: -i${srcdir}/lib
// #include "lib.c"
import "c"
func main() {
x := c.struct_foo{ x: 42 }
c.show(&x)
}
之所以有效,是因为我们实际上 #include 库的“c”源代码(隐式导入 lib/lib.h 文件)。
但是,对于更复杂的库,您可能需要将它们构建为单独的、更正常的 c 工具链,预构建步骤:
$ cd lib $ cc -c lib.c $ ar cr libx.a lib.o $ cd ..
然后使用不同的go文件:main2.go:
package main
// #cgo CFLAGS: -I${SRCDIR}/lib
// #cgo LDFLAGS: -L${SRCDIR}/lib -lx
// #include "lib.h"
import "C"
func main() {
x := C.struct_foo{ x: 42 }
C.show(&x)
}以上就是无法用cgo编译的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号