The JRuby team is proud to announce the release of FFI for Ruby 1.8.6/7
and 1.9!
FFI (gem install ffi) is a library for programmatically loading dynamic
libraries, binding functions within them, and calling those functions
from Ruby code. Here's a quick sample of binding and calling the getpid
C library function:
require 'ffi'
module GetPid
extend FFI::Library
attach_function :getpid, [], :uint
end
puts GetPid.getpid
Here's another, calling qsort and passing a Ruby block as a C callback:
require 'ffi'
module LibC
extend FFI::Library
callback :qsort_cmp, [
ointer,
ointer ], :int attach_function
:qsort, [
ointer, :int, :int, :qsort_cmp ], :int
end
p = MemoryPointer.new
int, 2)
p.put_array_of_int32(0, [ 2, 1 ])
puts "Before qsort #{p.get_array_of_int32(0, 2).join(', ')}"
LibC.qsort(p, 2, 4) do |p1, p2|
i1 = p1.get_int32(0)
i2 = p2.get_int32(0)
i1 < i2 ? -1 : i1 > i2 ? 1 : 0
end
puts "After qsort #{p.get_array_of_int32(0, 2).join(', ')}"
I posted a blog entry with a longer description of the library,
additional examples, and links to some other documentation and posts.
Docs are a little slim at this point, so feel free to experiment and
update the JRuby wiki page:
http://wiki.jruby.org/wiki/Calling_C_from_JRuby
I'm sure docs from here will filter back into the library and out into
the general cosmos.
Finally, there's no need to write a C extension to call C libraries, and
the same FFI code will work in Ruby 1.8.6/7, Ruby 1.9, JRuby 1.1.4+, and
Rubinius (though Rubinius has no callback support yet).
Don't be an extension stooge! Use FFI!
- Charlie