Dar*_*tle 70
Go 1.5添加了对构建可从C调用的共享库的支持(因此可以通过FFI从Ruby调用).这使得该过程比1.5之前的版本更容易(当需要编写C粘合层时),并且Go运行时现在可用,这使得它在现实生活中真正有用(goroutines和内存分配之前是不可能的,因为它们需要Go运行时,如果Go不是主要入口点,则无法使用它.
goFuncs.go:
package main
import "C"
//export GoAdd
func GoAdd(a, b C.int) C.int {
return a + b
}
func main() {} // Required but ignored
Run Code Online (Sandbox Code Playgroud)
请注意,//export GoAdd每个导出函数都需要注释; 后面的符号export是如何导出函数.
goFromRuby.rb:
require 'ffi'
module GoFuncs
extend FFI::Library
ffi_lib './goFuncs.so'
attach_function :GoAdd, [:int, :int], :int
end
puts GoFuncs.GoAdd(41, 1)
Run Code Online (Sandbox Code Playgroud)
该库是用以下内容构建的:
go build -buildmode=c-shared -o goFuncs.so goFuncs.go
Run Code Online (Sandbox Code Playgroud)
运行Ruby脚本会产生:
42
Nic*_*k P 11
通常情况下,我会尝试给你一个直接的答案,但到目前为止的评论显示可能没有.所以,希望这个通用解决方案和其他一些可能性的答案是可以接受的.
一个通用的解决方案:将高级语言程序编译到可从C语言调用的库中.为Ruby编译.在这一点上,必须非常小心集成.这个技巧是过去整合多种语言的好方法,通常是出于遗留原因.事实上,我不是Go开发人员,我不知道你可以编译Go进入可以从C调用的东西.继续.
创建两个独立程序:Ruby和Go程序.在程序中,使用一种非常有效的来回传递数据的方法.扩展将简单地建立与Go程序的连接,发送数据,等待结果,并将结果传递回Ruby.通信通道可能是OS IPC,套接字等.无论每个支持什么.如果没有安全问题并且您使用预定义的消息格式,则数据格式可以非常简单.这进一步提高了速度.我的一些旧程序使用XDR作为二进制格式.现在,人们似乎使用JSON,Protocol Buffers和ZeroMQ样式的线协议之类的东西.
第二个建议的变化:使用ZeroMQ!或类似的东西.ZeroMQ快速,强大,并且具有两种语言的绑定.它为您管理整个上段.缺点是它在性能调整方面不够灵活,并且有额外的东西你不需要.
使用两个进程并在它们之间传递数据的棘手部分是速度惩罚.离开Ruby可能不合理.但是,Go具有出色的本机性能和并发特性,可以证明编写应用程序的一部分是合理的,而不是像Ruby这样的脚本语言.(可能是你提出问题的理由之一.)所以,试试这些策略.如果您的工作程序也更快,请使用它.否则,坚持使用Ruby.
可能不太吸引人的选择:使用具有类似优势的Go以外的其他东西,允许从C调用,并且可以集成.虽然它不是很受欢迎,Ada是一种可能性.它长期以来一直强于本地代码,(受限制)的并发性,可靠性,低级别的支持,跨语言的发展和IDE(GNAT).此外,Julia是高性能技术和并行编程的新语言,可以编译成可从C调用的库.它也有一个JIT.也许从Ruby + Go到Ruby +(更合适的语言)改变问题陈述会解决问题吗?