Go共享库作为c++插件

Go shared library as C++ plugin

本文关键字:c++ 插件 共享 Go      更新时间:2023-10-16

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

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

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

  • gc似乎不支持共享库(即使https://code.google.com/p/go/issues/detail?id=256提到它)
  • gccgo支持Go共享库,但我无法使其工作(可能是因为主要入口点不在Go中…)
  • SWIG似乎也没有帮助:(

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

c

extern void Print(void) __asm__ ("example.main.Print");
int main() {
        Print();
}

print.go

package main
import "fmt"
func Print() {
    fmt.Printf("hello, worldn")
}

Makefile:

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'

有解决方案吗?最好的方法是什么?

引用:

  • go - go wiki
  • 回调
  • c回调和非go线程
  • go - golang
  • 从c
  • 调用go函数
  • 链接c代码与go代码

我不认为你可以把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()
}

c

#include <stdio.h>
// Defined in Go
extern void Print(void);
// C Main program
int cmain() {
  printf("Hello from Cn");
  Print();
}

print.go

package main
import "fmt"
import "C"
//export Print
func Print() {
    fmt.Printf("Hello from Gon")
}

使用go build编译,并在运行它时产生以下输出

Hello from C
Hello from Go

抱歉,您不能使用'gc' ATM将Go包编译为共享库,将来可能会更改。可能有一些机会与'gccgo'作为'libgo' (Go运行时,我想)是一个共享库已经。我猜缺失的部分,然后只有正确初始化运行时,这通常是一个Go命令自动处理。

gccgo专家是I.L. Taylor,几乎每天都可以在golang-nuts的邮件列表中找到他。我建议你直接问他。

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