この記事はSansanアドベントカレンダー、ネタ枠のHaiToがお送りしています。
Introduction
モンハンでリオレウスに蹂躙されながら考えていたりした。カレンダー登録したは良いけどネタがないなぁと。
Rubyの事を書こうとおもっても、最近fogの実装を細かく見る機会があって、fogが唐突にExcon::Errorを返してくるファッキンな部分とかと書いても、あんまりタメになる話っぽくておもしろくない上手く書ける気がしない。
大剣のストライカーは楽だなぁとか思いつつやっぱりエアリアルも捨てがたいけど、まぁブシドーいいよねとか思いつつ、
ここ二年くらいRubyばっかり触っていて、たまには他の言語を触りたくなるし、より高速な処理をしたいときは以前書いていたC++とかDlangのような感じでコンパイルをしてでも処理をしたかったりするときもある。
そんなことを常々思っていたりいなかったりした。
ふと、最近触りだしたGo
言語が偶然にもコンパイルが必要な言語で、もちろん早いし、それに加えて
弊社随一のOSS コミッター オーナーの shimat
さんが以前社内で ffi
なるライブラリを紹介していたのを思い出した。
この辺で遊んでみるか。
そう決めて一落ちした。
main
ffi ?
何も考えずにWikipediaを引用してみる。
Foreign function interface (FFI)とは、あるプログラミング言語から他のプログラミング言語で定義された関数などを利用するための機構。主に高水準言語からC/C++などの関数やメソッドを呼び出し、OS固有の機能などを利用するために使用されることが多い。
wikipedia
この時に「高水準言語」が今回はRubyで、C/C++は今回はGoだ。
えっ、 C は高水準言語言語だって!? ちょっとごめんなさい何を言っているのかわからないです><;
ffi/ffi がその実装だ。
https://github.com/ffi/ffi
Wikiも充実している。
英語である点だけを除けば
つまりライブラリとして用意しておき、それを呼び出せばよい。
この辺を参考にした。 http://yamaimo.hatenablog.jp/entry/2015/05/21/200000
Go をライブラリとしてBuildするのはこういう感じ。
$ cat sum.go
package main
import "C"
//export add
func add(a, b int) int {
return a + b
}
func main() {}
$ go build -buildmode=c-shared -o libsum.so sum.go
こうすると libsum.go というライブラリが爆誕するので、これを使えば良い。
require 'ffi'
module Sum
extend FFI::Library
ffi_lib './libsum.so'
# attach_function :method_name, [:args_type, :args_type], :return_type
attach_function :add, [:int, :int], :int
end
p Sum.add(1, 2) #=> 3
引数に使える型(int64とかstringとか以外)を増やすこともできるんですが(Struct)、CとかC++とかで増やし方はわかるんですが、Goではわかりませんでした
まとめ
とか思って、RubyKaigiで捕まらないWi-fiネットワーク越しにこの記事を投稿しようとしていたら、Ruby meets Goのセッションでこれ以上にためになる話をしてくれていたので、きっとすぐそちらの記事がでます!!!!!!!!!!!!!!ありがとうございます!!!!!!!!!!!!!!!!!