繁体   English   中英

在现有的 C 项目中使用 Go 代码

[英]Using Go code in an existing C project

自从 Go 1.5 出来后,我开始重新审视如何将它集成到我现有的项目中。

该项目的代码库完全用 C 编写,用于对硬件和其他有趣内容的低级别访问。 然而,一些更高级的东西很乏味,我想开始用更高级的语言(Go)来写它们

有什么办法可以从 C 程序中调用 Go 代码吗? 我安装了 Go 1.5,其中添加了-buildmode=c-archive ( https://golang.org/s/execmodes ),我正试图开始工作。

但是,我似乎无法获得 Go 来生成适当的 header 文件以允许我的项目实际编译。 当我生成存档时,我在导出的符号中看到 function(使用 objdump),但没有 header 文件包含 gcc 抱怨 function 不存在(如预期的那样)

我是 Go 的新手 - 但是,我喜欢这种语言并想使用它。 有没有什么惯用的方法(“惯用的”在我看到的 Go 的世界中被大量使用......)让这个相互配合得很好?

我问这个问题并特别提到 Go 1.5 的原因是,根据本文档, https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli=1#heading=h.1gw5y164088 1681 881支持非Go程序调用Go代码。 具体来说,在“Go code linked into, and called from, a non-Go program”一节中提到

要构建可从C调用的档案,您需要将其标记为导出的CGo符号。
例如,如果我使用以下内容创建文件foo.go

package main

import (
    "C"
    "fmt"
)

//export PrintInt
func PrintInt(x int) {
    fmt.Println(x)
}

func main() {}

要注意的重要事项是:

  • 该软件包需要称为main
  • 您需要具有main功能,尽管它可以为空。
  • 您需要导入软件包C
  • 您需要特殊的//export注释来标记要从C调用的函数。

我可以使用以下命令将其编译为C可调用静态库:

go build -buildmode=c-archive foo.go

其结果将是一个存档foo.a和头foo.h 在标题中,我们得到以下内容(不相关的部分):

...
typedef long long GoInt64;
...
typedef GoInt64 GoInt;
...
extern void PrintInt(GoInt p0);
...

这样就足以调用导出的函数。 我们可以编写一个简单的C程序来调用它,如下所示:

#include "foo.h"

int main(int argc, char **argv) {
    PrintInt(42);
    return 0;
}

我们可以使用以下命令来编译它:

gcc -pthread foo.c foo.a -o foo

需要-pthread选项,因为Go运行时使用了线程。 当我运行生成的可执行文件时,它会打印42

上面的代码工作得很好,但是 gcc 会抱怨函数和头文件。

包括应该是:

#define _GNU_SOURCE
#include <stdio.h>
#include "mygopkg.h"

如果您忘记了#define _GNU_SOURCE , gcc 会抱怨:

warning: implicit declaration of function 'asprintf'; did you mean 'vsprintf'? [-Wimplicit-function-declaration]

如果你忘记了#include "mygopkg.h" , gcc 会报错:

warning: implicit declaration of function 'PrintString' [-Wimplicit-function-declaration]

最后一点但同样重要。 我为生产代码推荐的构建命令行是:

go build -ldflags "-s -w"  -buildmode c-archive -o mygopkg.a

它将为您节省 53% 的最终 mygopkg.a 大小

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM