在GO中使库可以从其他语言中使用

Making a library usable from other languages in GO

本文关键字:其他 语言 GO      更新时间:2023-10-16

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

不幸的是,这不可能直接("可以被称为")。对于平台的C实现(对于大多数/所有官方支持的平台)所定义的内容,存在一些问题:

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

以上所有内容都适用于"gc"。"gccgo"在一定程度上也是如此。有关此方面的详细信息,请参阅C_Interoperability。

您的最佳选择是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}