使GO语言中的库可用于其他语言

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

Making a library usable from other languages in GO

问题

这可能看起来像一个愚蠢的问题,但是在GO语言中编写一个可以从其他语言(例如C++)调用的库是可能的吗?

英文:

This might seem like a silly question, but is it possible to write a library in GO that can be called from other languages, e.g. C++?

答案1

得分: 6

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

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

以上所有内容都适用于'gc'。在'gccgo'中,这种情况在一定程度上得到了放宽。有关更多信息,请参阅C C_Interoperability

英文:

That's unfortunately not directly ("can be called") possible. There are some issues wrt what is defined by the platform's C implementation (for most/all of the officially supported platforms):

  • Calling convention is not the same: For example, Go functions/methods don't use any registers for return values (if any).
  • Execution model is different: Split stacks are used.
  • Garbage collector may get confused by memory owned by the process but not "registered" by the GC as either "non-collectable" or specially marked (for precise collection).
  • Initialization of the Go runtime is a problem. It expects to be done before anything else in the process. If you would link with more than one Go .so, no ready made mechanism for coordination of the initialization exists.

All of the above applies to 'gc'. The same is to certain extent relaxed in 'gccgo'. More info about this in C C_Interoperability.

答案2

得分: 1

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

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

Your best bet is JSON-RPC. I've been looking around for ways to integrate legacy Python code with Go, to no success, until I found this.
If your data structures can be converted to JSON, you are good to go.
Here's a silly example:

Go JSON-RPC server

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 client

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)

Response

{"id":1,"result":"Hello, World","error":null}

huangapple
  • 本文由 发表于 2013年7月17日 18:37:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/17697531.html
匿名

发表评论

匿名网友

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

确定