2

这似乎是一个愚蠢的问题,但是是否可以在 GO 中编写一个可以从其他语言(例如 C++)调用的库?

4

2 回答 2

6

不幸的是,这不可能直接(“可以调用”)。平台的 C 实现定义了一些问题(对于大多数/所有官方支持的平台):

  • 调用约定不一样:例如,Go 函数/方法不使用任何寄存器作为返回值(如果有)。
  • 执行模型不同:使用拆分堆栈。
  • 垃圾收集器可能会被进程拥有但未被 GC“注册”为“不可收集”或特别标记(用于精确收集)的内存混淆。
  • Go 运行时的初始化是一个问题。它希望在过程中的其他任何事情之前完成。如果您要链接多个 Go .so,则不存在用于协调初始化的现成机制。

以上所有内容都适用于“gc”。在'gccgo'中也有一定程度的放松。C C_Interoperability中有关此的更多信息。

于 2013-07-17T11:00:27.763 回答
1

你最好的选择是 JSON-RPC。我一直在寻找将遗留 Python 代码与 Go 集成的方法,但没有成功,直到我找到了这个。如果您的数据结构可以转换为 JSON,那么您就可以开始了。这是一个愚蠢的例子:

转到 JSON-RPC 服务器

import (
    "log"
    "net"
    "net/rpc"
    "net/rpc/jsonrpc"
)

type Experiment int

func (e *Experiment) Test(i *string, reply *string) error {
    s := "Hello, " + *i
    *reply = s
    log.Println(s, reply)
    return nil
}

func main() {
    exp := new(Experiment)
    server := rpc.NewServer()
    server.Register(exp)
    l, err := net.Listen("tcp", ":1234")
    if err != nil {
        log.Fatal("listen error:", err)
    }
    for {
        conn, err := l.Accept()
        if err != nil {
            log.Fatal(err)
        }
        server.ServeCodec(jsonrpc.NewServerCodec(conn))
    }
}

Python 客户端

import json
import socket
s = socket.create_connection(("127.0.0.1", 1234))
s.sendall(json.dumps(({"id": 1, "method": "Experiment.Test", "params": ["World"]})))
print s.recv(4096)

回复

{"id":1,"result":"Hello, World","error":null}
于 2013-07-18T13:11:32.770 回答