本文将会介绍,使用Go语言编写 Ruby的扩展程序
Ruby-FFI
Ruby-FFI 是一个以编程的方式加载动态扩展库,绑定函数,并且能够在ruby中直接执行的 ruby 扩展包,使用FFI 提供的DSL语法,可以很灵活,优雅的调用C扩展程序。
Cgo
简单的说cgo就是通过加载C库 **import "C" ** ,然后可以在编译的时候,将文件注释中的C代码编译连接到当前的go程序中,这样就可以实现了 C程序和Go的相互调用。
实例
安装go
➜ $ brew install go
==> Downloading https://homebrew.bintray.com/bottles/go-1.5.3.el_capitan.bottle.tar.gz
######################################################################## 100.0%
==> Pouring go-1.5.3.el_capitan.bottle.tar.gz
==> Caveats
As of go 1.2, a valid GOPATH is required to use the `go get` command:
https://golang.org/doc/code.html#GOPATH
You may wish to add the GOROOT-based install location to your PATH:
export PATH=$PATH:/usr/local/opt/go/libexec/bin
==> Summary
🍺 /usr/local/Cellar/go/1.5.3: 5,336 files, 259.6M
安装 ffi
➜ $ gem install ffi
Building native extensions. This could take a while...
Successfully installed ffi-1.9.10
Parsing documentation for ffi-1.9.10
Done installing documentation for ffi after 0 seconds
1 gem installed
go函数
** sum.go **
package main
import "C"
//export sum
func sum(x, y int) int {
return x + y
}
func main(){}
这里使用在cgo中作为函数输出的注释标记 //export 标识出这个文件输出的函数
编译go程序
go build -buildmode=c-shared -o sum.so sum.go
在Ruby中调用Go函数
** sum.rb **
require 'ffi'
module Maths
extend FFI::Library
ffi_lib './sum.so'
attach_function :sum, [:int, :int], :int
end
puts Maths.sum(ARGV[0].to_i, ARGV[1].to_i)
# ruby sum.rb 23 60
# => 83
总结
使用Go编写ruby扩展,相对于使用更底层的C语言编写扩展来说,更容易和更有趣一些。在本文实例中只是简单介绍了如何在ruby中使用Go扩展,但在具体的场景中这种方式还会遇到一些问题,比如,不是所有的Go程序都可以编译成C扩展,goroutine的并发特性不能应用到Ruby中,Go语言和C程序的交互还是有一些性能问题等,所以如果是要在生产环境使用Go编写扩展的话,还是需要根据应用的场景来判断是否适合。