Go共享库作为C++插件

huangapple go评论111阅读模式
英文:

Go shared library as C++ plugin

问题

我有一个项目,我想在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/)

main.c

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

int main() {
        Print();
}

print.go

package main

import "fmt"

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

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

Output :

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

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

参考资料:

英文:

I have a project where I would like to load Go plugins inside a C++ application.

After a lot of research, it is not clear for me whether or not Go supports this.
I encountered a lot of discussions pointing out the bad habit of dynamic linking, proning IPC instead. Moreover it is not clear for me if dynamic linking is intended by the language or not (new Go philosophy ?).

cgo provides the ability to call C from Go or Go from C (inside Go), but not from plain old C. Or does it ?

  • gc doesn't seem to support shared library (even if https://code.google.com/p/go/issues/detail?id=256 mentions it does)
  • gccgo support Go shared libraries but I couldn't make it work (probably because the main entry point is not in Go ...)
  • SWIG doesn't seem to help either Go共享库作为C++插件

Apparently something is going on upstream as well (https://codereview.appspot.com/7304104/)

main.c

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

int main() {
        Print();
}

print.go

package main

import "fmt"

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

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

Output :

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

Is there a solution for that ? What is the best approach ? forking + IPC ?

References :

答案1

得分: 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()
}

main.c

#include <stdio.h>

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

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

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
英文:

I don't think you can embed Go into C. However you can embed C into Go and with a little stub C program you can call into C first thing which is the next best thing! Cgo definitely supports linking with shared libraries so maybe this approach will work for you.

Like this

main.go

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

// extern int cmain(void);
import &quot;C&quot;

func main() {
     C.cmain()
}

main.c

#include &lt;stdio.h&gt;

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

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

print.go

package main

import &quot;fmt&quot;

import &quot;C&quot;

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

Compile with go build, and produces this output when you run it

Hello from C
Hello from Go

答案2

得分: 2

据我所知,目前无法使用'gc'将Go包编译为共享库,但这可能会在将来发生改变。使用'gccgo'可能有一些机会,因为'libgo'(我猜是Go运行时)已经是一个共享库。我猜缺失的部分只是正确初始化运行时,通常由Go命令自动处理。

gccgo专家是I.L. Taylor,他几乎每天都可以在golang-nuts邮件列表上联系到。建议直接向他提问。

附注:其他可能存在的问题可能包括Go垃圾收集器与(C++)进程内存的交互等。也许我过于乐观,这根本不可行。

英文:

AFAIK, you cannot compile a Go package to a shared library witg 'gc' ATM, it may change in the future. There might be some chance with 'gccgo' as 'libgo' (Go runtime, I suppose) is a shared library already. I guess the missing piece is then only to properly initialize the runtime, which normally a Go command handles automatically.

The gccgo expert is I.L. Taylor, he is reachable at the golang-nuts mailing list almost daily. I suggest to ask him directly.

PS: Other problems possibly include the interaction of the Go garbage collector and the (C++) process memory etc. Maybe I'm too optimistic and it is not at all feasible.

huangapple
  • 本文由 发表于 2013年5月29日 13:21:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/16806060.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定