英文:
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}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论