3

我有一个项目,我想在 C++ 应用程序中加载 Go 插件。

经过大量研究,我不清楚 Go 是否支持这一点。我遇到很多讨论指出动态链接的坏习惯,而不是使用 IPC。此外,我不清楚动态链接是否是该语言的意图(新的 Go 哲学?)。

cgo 提供了从 Go 调用 C 或从 C(在 Go 内部)调用 Go 的能力,但不能从普通的旧 C 调用。或者是吗?

显然上游也发生了一些事情(https://codereview.appspot.com/7304104/

主程序

extern void Print(void) __asm__ ("example.main.Print");

int main() {
        Print();
}

打印.go

package main

import "fmt"

func Print() {
    fmt.Printf("hello, world\n")
}

生成文件:

all: print.o main.c
        gcc main.c -L. -lprint -o main

print.o: print.go
        gccgo -fno-split-stack -fgo-prefix=example -fPIC -c print.go -o print.o
        gccgo -shared print.o -o libprint.so

输出 :

/usr/lib/libgo.so.3: undefined reference to `main.main'
/usr/lib/libgo.so.3: undefined reference to `__go_init_main'

有解决方案吗?最好的方法是什么?分叉+IPC?

参考 :

4

2 回答 2

7

我不认为你可以将 Go 嵌入到 C 中。但是你可以将 C 嵌入到 Go 中,并且通过一个小的存根 C 程序,你可以首先调用 C,这是下一个最好的事情!Cgo 绝对支持与共享库的链接,所以也许这种方法对你有用。

像这样

main.go

// Stub go program to call cmain() in C
package main

// extern int cmain(void);
import "C"

func main() {
     C.cmain()
}

主程序

#include <stdio.h>

// Defined in Go
extern void Print(void);

// C Main program
int cmain() {
  printf("Hello from C\n");
  Print();
}

打印.go

package main

import "fmt"

import "C"

//export Print
func Print() {
    fmt.Printf("Hello from Go\n")
}

编译go build,并在运行时生成此输出

Hello from C
Hello from Go
于 2013-05-29T06:28:15.450 回答
2

AFAIK,你不能将 Go 包编译到共享库 wtg 'gc' ATM,它将来可能会改变。'gccgo' 可能有一些机会,因为'libgo'(我想是 Go 运行时)已经是一个共享库。我猜缺少的部分只是正确初始化运行时,通常 Go 命令会自动处理。

gccgo 专家是 IL Taylor,几乎每天都可以通过 golang-nuts 邮件列表联系到他。我建议直接问他。

PS:其他问题可能包括Go垃圾收集器和(C++)进程内存的交互等。可能我太乐观了,根本不可行。

于 2013-05-29T06:09:31.040 回答