ffi -- creating cross engine rubygems
DESCRIPTION
FFI is a way to create cross engine rubygems. Wrap a library once, and use it from MRI, JRuby, Rubinious, and mingw32 Ruby. This talk will discuss FFI why you want to use it.TRANSCRIPT
![Page 1: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/1.jpg)
FFIMAKING CROSS ENGINE EXTENSIONS
Jeremy [email protected]
twitter : copiousfreetime
1Tuesday, November 24, 2009
![Page 2: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/2.jpg)
I LOVE RUBY
2Tuesday, November 24, 2009
![Page 3: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/3.jpg)
I LIKE C
3Tuesday, November 24, 2009
![Page 4: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/4.jpg)
SURVEY TIME
4Tuesday, November 24, 2009
![Page 5: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/5.jpg)
RUBY DEVELOPERS?
5Tuesday, November 24, 2009
![Page 6: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/6.jpg)
WRITER OF LIBRARIES?
6Tuesday, November 24, 2009
![Page 7: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/7.jpg)
WRITER OF EXTENSIONS?
7Tuesday, November 24, 2009
![Page 8: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/8.jpg)
USED BY MULTIPLE ENGINES?
8Tuesday, November 24, 2009
![Page 9: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/9.jpg)
WHAT IS FFI?
9Tuesday, November 24, 2009
![Page 10: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/10.jpg)
LIBFFIhttp://sourceware.org/libffi/
“A foreign function interface is the popular name for the interface that allows code written in one language
to call code written in another language.”
10Tuesday, November 24, 2009
![Page 11: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/11.jpg)
FOR RUBYISTS
The Goal :
An extension based upon FFI should be compatible with many ruby
engines.
11Tuesday, November 24, 2009
![Page 12: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/12.jpg)
libfoo.so
12Tuesday, November 24, 2009
![Page 13: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/13.jpg)
libfoo.so
Applicationuses
libfoo_bar()
12Tuesday, November 24, 2009
![Page 14: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/14.jpg)
libfoo.so
Applicationuses
libfoo_bar()
FFI
12Tuesday, November 24, 2009
![Page 15: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/15.jpg)
libfoo.so
Applicationuses
libfoo_bar()
FFIRuntim
e
12Tuesday, November 24, 2009
![Page 16: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/16.jpg)
libfoo.so
ruby-foo C extension
Matz RubyInterpreter
App
13Tuesday, November 24, 2009
![Page 17: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/17.jpg)
libfoo.so
ruby-foo C extension
Matz RubyInterpreter
App
JRubyInterpreter
App
RubiniusInterpreter
App
13Tuesday, November 24, 2009
![Page 18: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/18.jpg)
libfoo.so
Matz RubyInterpreter
App
JRubyInterpreter
App
RubiniusInterpreter
App
13Tuesday, November 24, 2009
![Page 19: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/19.jpg)
libfoo.so
Matz RubyInterpreter
App
JRubyInterpreter
App
RubiniusInterpreter
App
13Tuesday, November 24, 2009
![Page 20: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/20.jpg)
libfoo.so
Matz RubyInterpreter
App
JRubyInterpreter
App
RubiniusInterpreter
App
built-in libffi or ffi gem
13Tuesday, November 24, 2009
![Page 21: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/21.jpg)
libfoo.so
Matz RubyInterpreter
App
JRubyInterpreter
App
RubiniusInterpreter
App
built-in libffi or ffi gem
foo-ffi (pure ruby)
13Tuesday, November 24, 2009
![Page 22: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/22.jpg)
LIBSIMPLE_METRICShttp://github.com/copiousfreetime/libsimple_metrics
14Tuesday, November 24, 2009
![Page 23: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/23.jpg)
1 #ifndef __SIMPLE_METRICS_H__ 2 #define __SIMPLE_METRICS_H__ 3 #include <stdlib.h> 4 #include <math.h> 5 6 typedef struct _simple_metrics{ 7 double min; 8 double max; 9 double sum;10 double sumsq;11 long count;12 } simple_metrics ;13 14 simple_metrics* simple_metrics_new();15 void simple_metrics_free( simple_metrics* sm );16 void simple_metrics_update( simple_metrics* sm, double value );17 double simple_metrics_mean( simple_metrics* sm );18 double simple_metrics_min( simple_metrics* sm );19 double simple_metrics_max( simple_metrics* sm );20 double simple_metrics_sum( simple_metrics* sm );21 long simple_metrics_count( simple_metrics* sm );22 double simple_metrics_stddev( simple_metrics* sm );23 double simple_metrics_rate( simple_metrics* sm );24 25 #endif
15Tuesday, November 24, 2009
![Page 24: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/24.jpg)
1 class Metric 2 attr_reader :name 3 def initialize( name ) 4 @name 5 end 6 7 def update( new_value) ... end 8 def count ... end 9 def max ... end10 def mean ... end11 def min ... end12 def rate ... end13 def sum ... end14 def stddev ... end15 end
16Tuesday, November 24, 2009
![Page 25: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/25.jpg)
142 void Init_simple_metrics_ext()143 {144 VALUE cSM_Common;145 146 mSM = rb_define_module( "SimpleMetrics" );147 mSME = rb_define_module_under( mSM, "Ext" );148 149 /* load the class we inherit from */150 rb_require("simplemetrics/common");151 152 cSM_Common = rb_const_get( mSM, rb_intern( "Common" ) );153 154 cSME_Metric = rb_define_class_under( mSME, "Metric", cSM_Common );155 156 rb_define_alloc_func(cSME_Metric, sm_alloc); 157 rb_define_method( cSME_Metric, "initialize", sm_initialize, 1 );158 rb_define_method( cSME_Metric, "update", sm_update, 1 );159 rb_define_method( cSME_Metric, "count", sm_count, 0 );160 rb_define_method( cSME_Metric, "max", sm_max, 0 );161 rb_define_method( cSME_Metric, "min", sm_min, 0 );162 rb_define_method( cSME_Metric, "mean", sm_mean, 0 );163 rb_define_method( cSME_Metric, "rate", sm_rate, 0 );164 rb_define_method( cSME_Metric, "sum", sm_sum, 0 );165 rb_define_method( cSME_Metric, "stddev", sm_stddev, 0 );166 167 }
17Tuesday, November 24, 2009
![Page 26: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/26.jpg)
142 void Init_simple_metrics_ext()143 {144 VALUE cSM_Common;145 146 mSM = rb_define_module( "SimpleMetrics" );147 mSME = rb_define_module_under( mSM, "Ext" );148 149 /* load the class we inherit from */150 rb_require("simplemetrics/common");151 152 cSM_Common = rb_const_get( mSM, rb_intern( "Common" ) );153 154 cSME_Metric = rb_define_class_under( mSME, "Metric", cSM_Common );155 156 rb_define_alloc_func(cSME_Metric, sm_alloc); 157 rb_define_method( cSME_Metric, "initialize", sm_initialize, 1 );158 rb_define_method( cSME_Metric, "update", sm_update, 1 );159 rb_define_method( cSME_Metric, "count", sm_count, 0 );160 rb_define_method( cSME_Metric, "max", sm_max, 0 );161 rb_define_method( cSME_Metric, "min", sm_min, 0 );162 rb_define_method( cSME_Metric, "mean", sm_mean, 0 );163 rb_define_method( cSME_Metric, "rate", sm_rate, 0 );164 rb_define_method( cSME_Metric, "sum", sm_sum, 0 );165 rb_define_method( cSME_Metric, "stddev", sm_stddev, 0 );166 167 }
17Tuesday, November 24, 2009
![Page 27: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/27.jpg)
7 module SimpleMetrics 8 module FFI 9 10 class Struct < ::FFI::ManagedStruct11 layout :min, :double, :max, :double, :sum, :double, 12 :sumsq, :double, :count, :long13 def self.release( ptr )14 SimpleMetrics::FFI.simple_metrics_free( ptr )15 end16 end17 18 extend ::FFI::Library19 ffi_lib "libsimple_metrics"20 21 attach_function :simple_metrics_new, [ ], :pointer22 attach_function :simple_metrics_free, [ :pointer ], :void23 attach_function :simple_metrics_update,[ :pointer, :double ], :void24 attach_function :simple_metrics_min, [ :pointer ], :double25 attach_function :simple_metrics_max, [ :pointer ], :double26 attach_function :simple_metrics_mean, [ :pointer ], :double27 attach_function :simple_metrics_sum, [ :pointer ], :double28 attach_function :simple_metrics_count, [ :pointer ], :long29 attach_function :simple_metrics_stddev,[ :pointer ], :double30 attach_function :simple_metrics_rate, [ :pointer ], :double31 32 end33 end
18Tuesday, November 24, 2009
![Page 28: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/28.jpg)
7 module SimpleMetrics 8 module FFI 9 10 class Struct < ::FFI::ManagedStruct11 layout :min, :double, :max, :double, :sum, :double, 12 :sumsq, :double, :count, :long13 def self.release( ptr )14 SimpleMetrics::FFI.simple_metrics_free( ptr )15 end16 end17 18 extend ::FFI::Library19 ffi_lib "libsimple_metrics"20 21 attach_function :simple_metrics_new, [ ], :pointer22 attach_function :simple_metrics_free, [ :pointer ], :void23 attach_function :simple_metrics_update,[ :pointer, :double ], :void24 attach_function :simple_metrics_min, [ :pointer ], :double25 attach_function :simple_metrics_max, [ :pointer ], :double26 attach_function :simple_metrics_mean, [ :pointer ], :double27 attach_function :simple_metrics_sum, [ :pointer ], :double28 attach_function :simple_metrics_count, [ :pointer ], :long29 attach_function :simple_metrics_stddev,[ :pointer ], :double30 attach_function :simple_metrics_rate, [ :pointer ], :double31 32 end33 end
library function parameters return type
18Tuesday, November 24, 2009
![Page 29: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/29.jpg)
35 module SimpleMetrics36 module FFI37 class Metric < ::SimpleMetrics::Common38 include ::SimpleMetrics::FFI39 def initialize( name )40 super41 @impl = FFI.simple_metrics_new42 end43 44 def update( v )45 simple_metrics_update( @impl, v )46 end47 48 self.keys.each do |f|49 module_eval <<-code50 def #{f}51 simple_metrics_#{f}( @impl )52 end53 code54 end55 end56 end57 end
19Tuesday, November 24, 2009
![Page 30: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/30.jpg)
10 class Struct < ::FFI::ManagedStruct11 layout :min, :double, 12 :max, :double, 13 :sum, :double, 14 :sumsq, :double, 15 :count, :long16 def self.release( ptr )17 SimpleMetrics::FFI.simple_metrics_free( ptr )18 end19 end
6 typedef struct _simple_metrics{ 7 double min; 8 double max; 9 double sum;10 double sumsq;11 long count;12 } simple_metrics ;
20Tuesday, November 24, 2009
![Page 31: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/31.jpg)
14 simple_metrics* simple_metrics_new();15 void simple_metrics_free( simple_metrics* sm );16 void simple_metrics_update( simple_metrics* sm, double value );17 double simple_metrics_mean( simple_metrics* sm );18 double simple_metrics_min( simple_metrics* sm );19 double simple_metrics_max( simple_metrics* sm );20 double simple_metrics_sum( simple_metrics* sm );21 long simple_metrics_count( simple_metrics* sm );22 double simple_metrics_stddev( simple_metrics* sm );23 double simple_metrics_rate( simple_metrics* sm );
21 extend ::FFI::Library22 ffi_lib "libsimple_metrics"23 24 attach_function :simple_metrics_new, [ ], :pointer25 attach_function :simple_metrics_free, [ :pointer ], :void26 attach_function :simple_metrics_update,[ :pointer, :double ], :void27 attach_function :simple_metrics_mean, [ :pointer ], :double28 attach_function :simple_metrics_min, [ :pointer ], :double29 attach_function :simple_metrics_max, [ :pointer ], :double30 attach_function :simple_metrics_sum, [ :pointer ], :double31 attach_function :simple_metrics_count, [ :pointer ], :long32 attach_function :simple_metrics_stddev,[ :pointer ], :double33 attach_function :simple_metrics_rate, [ :pointer ], :double
21Tuesday, November 24, 2009
![Page 32: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/32.jpg)
FFI Traditional C Extension
Jeremy’s Time
1 Million update() calls
Will it Blend run on JRuby?
40 minutes 70 minutes
1.16 sec 0.42 sec
Yes No
MEANINGLESS METRICS
22Tuesday, November 24, 2009
![Page 33: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/33.jpg)
DEMO
23Tuesday, November 24, 2009
![Page 34: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/34.jpg)
% ruby example/bench.rb 1000000generating 1000000 random numbers between 0 and 10,000Rehearsal -----------------------------------------------ext 0.500000 0.000000 0.500000 ( 0.504501)ffi 0.960000 0.000000 0.960000 ( 0.956847)-------------------------------------- total: 1.460000sec
user system total realext 0.510000 0.000000 0.510000 ( 0.521388)ffi 0.940000 0.000000 0.940000 ( 0.946538)
% ~/pkgs/jruby-1.4.0/bin/jruby example/bench.rb 1000000generating 1000000 random numbers between 0 and 10,000Rehearsal -----------------------------------------------ffi 0.697000 0.000000 0.697000 ( 0.696000)-------------------------------------- total: 0.697000sec
user system total realffi 0.493000 0.000000 0.493000 ( 0.493000)
24Tuesday, November 24, 2009
![Page 35: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/35.jpg)
FFI BASED PROJECTS
Nokogiri ffi-wiiuse
Gnu Linear Programming Toolkit NiceFFI
Ruby-SDL-FFI
Rubygameffi-inliner
ffi-opengl
ffi-life
ffi-tccJohnson FFI port
rufus-tokyo
ffi-tk
Ruby-GIR-FFI
ffi-opencl
25Tuesday, November 24, 2009
![Page 36: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/36.jpg)
THANKS
•Wayne Meissner - adding libffi to JRuby and providing the ffi gem for MRI.
• Evan Phoenix - using libffi in Rubinius
• Authors of the examples on the ffi project wiki
26Tuesday, November 24, 2009
![Page 37: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/37.jpg)
LINKS
• http://github.com/ffi/ffi
• http://wmeissner.blogspot.com/
• http://groups.google.com/group/ruby-ffi
27Tuesday, November 24, 2009
![Page 38: FFI -- creating cross engine rubygems](https://reader035.vdocument.in/reader035/viewer/2022062312/5555a7c8d8b42a52568b4792/html5/thumbnails/38.jpg)
QUESTIONS?
28Tuesday, November 24, 2009