1

我正在尝试在我的 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 buildgun run.

我感觉我的#cgo命令无效(我不是 C 专家),

4

1 回答 1

3

对,它不适用于 ar 对象档案 ( *.a)。你可以做两件事:

  • 将其链接为共享库(-lfoo在库搜索路径中的inLDFLAGS和 with中)libfoo.so

  • *.c文件本身放在 Go 包目录中,以便go build构建和链接它们

但是,如果您愿意放弃标准go build行为,您可以将文件解压缩到单独的目标文件中,*.a然后手动模仿行为。go buildcgo

例如,如果您使用该-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您的包)。

于 2013-09-05T18:20:35.237 回答