ffi for rubyists
DESCRIPTION
introduction to ruby-ffiTRANSCRIPT
RubyistのためのFFI入門@nanki / 関西闇Ruby会議
自己紹介
@nanki ■
Ruby, JavaScript, Objective-[CJ]...
http://blog.netswitch.jp/ - 出町ミスド戦記
http://github.com/nanki
misdo.rb
misdo.rb
misdo.rb
全国のミスタードーナツで毎日開催
misdo.rb
全国のミスタードーナツで毎日開催
参加費 ドーナツ/コーヒー代(実費)
misdo.rb
全国のミスタードーナツで毎日開催
参加費 ドーナツ/コーヒー代(実費)
Rubyなどを使って自分のことをする
misdo.rb
全国のミスタードーナツで毎日開催
参加費 ドーナツ/コーヒー代(実費)
Rubyなどを使って自分のことをする
Ruby以外でもOK
misdo.rb
全国のミスタードーナツで毎日開催
参加費 ドーナツ/コーヒー代(実費)
Rubyなどを使って自分のことをする
Ruby以外でもOK
ミスドじゃなくてもOK
本題
RubyがCと向き合う方法
RubyがCと向き合う方法
拡張ライブラリを書く
RubyがCと向き合う方法
拡張ライブラリを書く
SWIGを使う
RubyがCと向き合う方法
拡張ライブラリを書く
SWIGを使う
FFI ☜ NEW!
FFIとは?
libffi
Foreign Function Interfaceの略
呼出規約(Calling Convention)に則って
無理矢理呼び出す
func(x1, x2, x3)
x3
func(x1, x2, x3)
x2
x3
func(x1, x2, x3)
x1
x2
x3
func(x1, x2, x3)
戻り先
x1
x2
x3
func(x1, x2, x3)
戻り先
x1
x2
x3
☞call!
func(x1, x2, x3)
♨
x2
x3
func(x1, x2, x3)
♨
x3
func(x1, x2, x3)
♨
func(x1, x2, x3)
func(x1, x2, x3)
おわり
ffi(ruby-ffi)
ffi
libffiをRubyから使うためのライブラリ
ffi
libffiをRubyから使うためのライブラリ
http://github.com/ffi/ffi
ffi
libffiをRubyから使うためのライブラリ
http://github.com/ffi/ffi
githubはRubyistだけのものではないのに…
ffi
libffiをRubyから使うためのライブラリ
http://github.com/ffi/ffi
githubはRubyistだけのものではないのに…
我が物顔でffi/ffi
ffi
フィッフィ?
フィッフィ入門@nanki / 闇西関Ruby会議
module LibC extend FFI::Library
ffi_lib 'c' # FFI::Library::LIBC
# int puts(char*) attach_function :puts, [:string], :intend
LibC.puts "Hello!"
使い方(1)
:short # 16bit int :int # 32bit int :long_long # 64bit int :long # long
:float # float :double # double :string # NULL-terminated :pointer # pointer
:void, :float, :double, :varargs, ...
使い方(2) 型
enum :Status, [:Success, 0, :Failure, 1]
class Pointer < FFI::Struct layout( :x, :float, :y, :float )end
callback :PaStreamFinishedCallback, [:pointer], :void
使い方(3) 型列挙型/構造体/関数ポインタ
module PA ffi_lib 'portaudio'
enum :PaStreamCallbackResult, [:paContinue, :paComplete, :paAbort]
class PaStreamCBTimeInfo < FFI::Struct layout(...) end
使い方(4) 例ffi-portaudioより抜粋
callback :PaStreamCallback, [..., PaStreamCBTimeInfo.in, ...], :PaStreamCallbackResult
attach_function :Pa_OpenStream, [..., :PaStreamCallback, ...], ...end
PA.Pa_OpenStream(..., c = lambda{|...| :paContinue}, ...)
使い方(5) 例ffi-portaudioより抜粋
callback :PaStreamCallback, [..., PaStreamCBTimeInfo.in, ...], :PaStreamCallbackResult
attach_function :Pa_OpenStream, [..., :PaStreamCallback, ...], ...end
PA.Pa_OpenStream(..., c = lambda{|...| :paContinue}, ...)
使い方(5) 例
☜
ffi-portaudioより抜粋
callback :PaStreamCallback, [..., PaStreamCBTimeInfo.in, ...], :PaStreamCallbackResult
attach_function :Pa_OpenStream, [..., :PaStreamCallback, ...], ...end
PA.Pa_OpenStream(..., c = lambda{|...| :paContinue}, ...)
使い方(5) 例
☜GC対策
ffi-portaudioより抜粋
なぜフィッフィか
なぜフィッフィか
なぜフィッフィか
ブリッジコード書きたい?
なぜフィッフィか
ブリッジコード書きたい?
SWIGで生成されたコードで…
なぜフィッフィか
ブリッジコード書きたい?
SWIGで生成されたコードで…
レポジトリが汚れない
なぜフィッフィか
ブリッジコード書きたい?
SWIGで生成されたコードで…
レポジトリが汚れない
Cのコードをメンテナンスしなくてよい
なぜフィッフィか
ブリッジコード書きたい?
SWIGで生成されたコードで…
レポジトリが汚れない
Cのコードをメンテナンスしなくてよい
(JRuby/Rubiniusなどでも使える)
拡張ライブラリ N/A
SWIG 5350行
フィッフィ 206行
なぜフィッフィかportaudioの場合
200行はフィッフィも結構面倒なのでは?
そこで…
♘ swig -module portaudio -o portaudio.xml -xml portaudio/include/portaudio.h
♘ ffi-gen portaudio.xml portaudio.rb
ffi-swig-generator
♘ swig -module portaudio -o portaudio.xml -xml portaudio/include/portaudio.h
♘ ffi-gen portaudio.xml portaudio.rb
ffi-swig-generator
SWIG便利
まとめ
まとめきれなかったもの
FFI::AutoPointer.new(pointer, self.class.method(:destuctor))
ffi-ruby(https://gist.github.com/1336545)
Unicodeにはffi(U+FB03)という文字がある
include FFI::Ruby
p FFI::Ruby::rb_ary_includes [1, 2], 2# => true
ary = rb_ary_newargv = FFI::MemoryPointer.new :pointer, 1argv.write_pointer rb_ary_to_s(ary)rb_io_puts 1, argv, FFI::Ruby.rb_stdout
# []
ffi-ruby
def from_native(value, ctx=nil) id = if value.address & 0x0f == 0xe value.address >> 8 else rb_num2long rb_obj_id value end ObjectSpace._id2ref idend
ffi-ruby
def to_native(obj, ctx=nil) id = obj.__id__ case obj when Symbol FFI::Pointer.new id << 8 | 0xe when Fixnum, FalseClass, TrueClass, NilClass FFI::Pointer.new id else FFI::Pointer.new id << 1 endend
ffi-ruby
♘ gem dependent ffi | wc -l192
フィッフィと仲間たち
192!
フィッフィと仲間たち
ⓒS4/C
http://cyw.s4c.co.uk/en/rhaglenni/ffi-ffi
ffi-ffi a'i Ffrindiau
RubyがC++と向き合う方法
闇