我正在尝试在Go程序中使用外部C库。
我尝试了以下内容:
package cgoexample
/*
#include <stdio.h>
#include <stdlib.h>
#cgo CFLAGS: -I/Users/me/somelib/include
#cgo LDFLAGS: /Users/me/somelib/libhello.a
#include "stinger.h"
void myprint(char* s) {
printf("%s", s);
}
*/
import "C"
import "unsafe"
//... more here
在/Users/me/somelib/include
中有.h文件,在libhello.a
中有.o文件(我使用ar
命令检查),其中包含已定义的函数.h文件。
似乎.h文件正在链接正常,但它看起来不像链接的存档文件。我一直得到这些:
warning: 'some_method_in_my_h_file" declared 'static' but never defined
这些警告被视为错误。无论如何,它们应该在存档文件中实现,所以我很困惑我在这里做错了。
当我运行go build
和gun run
时。
我感觉我的#cgo
命令无效(我不是C专家),
答案 0 :(得分:3)
是的,它不适用于ar对象存档(*.a
)。你可以做两件事:
将其作为共享库(-lfoo
中的LDFLAGS
与库搜索路径中的libfoo.so
相关联)
将*.c
文件放在Go包目录中,以便go build
构建并链接它们
但是,如果您愿意退出标准go build
行为,可以将*.a
文件解压缩到各个目标文件中,然后模仿go build
和cgo
的行为。
例如,如果您使用-x
选项构建一个简单的cgo示例包,您应该看到与此类似的输出:
% go build -x
(...)
.../cgo (...) sample.go
(...)
gcc -I . -g (...) -o $WORK/.../_obj/sample.o -c ./sample.c
(...)
gcc -I . -g (...) -o $WORK/.../_obj/_all.o (...) $WORK/.../_obj/sample.o
(...)
.../pack grcP $WORK $WORK/.../sample.a (...) .../_obj/_all.o
cd .
.../6l -o $WORK/.../a.out (...) $WORK/.../sample.a
(...)
因此,您可以看到*.c
正在编辑各个gcc
文件,这些文件打包在一个特定于Go的ar
存档中,然后由6l
链接。您也可以手动执行这些步骤,如果由于某种原因您真的无法将*.c
文件放在包目录中并让go build
为您处理它们(这会更简单并且给人们go get
你的包裹的机会。)