本文將會(huì)介紹智亮,使用Go語(yǔ)言編寫(xiě) Ruby的擴(kuò)展程序
Ruby-FFI
Ruby-FFI 是一個(gè)以編程的方式加載動(dòng)態(tài)擴(kuò)展庫(kù)克懊,綁定函數(shù)洋丐,并且能夠在ruby中直接執(zhí)行的 ruby 擴(kuò)展包豪诲,使用FFI 提供的DSL語(yǔ)法吊圾,可以很靈活达椰,優(yōu)雅的調(diào)用C擴(kuò)展程序。
Cgo
簡(jiǎn)單的說(shuō)cgo就是通過(guò)加載C庫(kù) **import "C" ** 项乒,然后可以在編譯的時(shí)候啰劲,將文件注釋中的C代碼編譯連接到當(dāng)前的go程序中,這樣就可以實(shí)現(xiàn)了 C程序和Go的相互調(diào)用檀何。
實(shí)例
安裝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函數(shù)
** sum.go **
package main
import "C"
//export sum
func sum(x, y int) int {
return x + y
}
func main(){}
這里使用在cgo中作為函數(shù)輸出的注釋標(biāo)記 //export 標(biāo)識(shí)出這個(gè)文件輸出的函數(shù)
編譯go程序
go build -buildmode=c-shared -o sum.so sum.go
在Ruby中調(diào)用Go函數(shù)
** 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
總結(jié)
使用Go編寫(xiě)ruby擴(kuò)展蝇裤,相對(duì)于使用更底層的C語(yǔ)言編寫(xiě)擴(kuò)展來(lái)說(shuō),更容易和更有趣一些频鉴。在本文實(shí)例中只是簡(jiǎn)單介紹了如何在ruby中使用Go擴(kuò)展栓辜,但在具體的場(chǎng)景中這種方式還會(huì)遇到一些問(wèn)題,比如垛孔,不是所有的Go程序都可以編譯成C擴(kuò)展藕甩,goroutine的并發(fā)特性不能應(yīng)用到Ruby中,Go語(yǔ)言和C程序的交互還是有一些性能問(wèn)題等周荐,所以如果是要在生產(chǎn)環(huán)境使用Go編寫(xiě)擴(kuò)展的話狭莱,還是需要根據(jù)應(yīng)用的場(chǎng)景來(lái)判斷是否適合。