[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

[ANN] FFI 0.1.1 (Foreign Function Interface) for Ruby 1.8.6/7 and 1.9

Charles Oliver Nutter

10/31/2008 11:17:00 PM

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, [ :pointer, :pointer ], :int
attach_function :qsort, [ :pointer, :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_...

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

60 Answers

Thomas Hurst

11/1/2008 1:39:00 AM

0

* Charles Oliver Nutter (charles.nutter@sun.com) wrote:

> The JRuby team is proud to announce the release of FFI for Ruby
> 1.8.6/7 and 1.9!

> 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).

Awesome. I've used DL to link up some custom libs to a Ruby service,
will give FFI a go and see how it compares :)

Are things like structs likely to be supported in future, ala Python
ctypes?

--
Thomas 'Freaky' Hurst
http...

Charles Oliver Nutter

11/1/2008 5:41:00 AM

0

Thomas Hurst wrote:
> * Charles Oliver Nutter (charles.nutter@sun.com) wrote:
>
>> The JRuby team is proud to announce the release of FFI for Ruby
>> 1.8.6/7 and 1.9!
>
>> 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).
>
> Awesome. I've used DL to link up some custom libs to a Ruby service,
> will give FFI a go and see how it compares :)
>
> Are things like structs likely to be supported in future, ala Python
> ctypes?

Actually structs are already supported! See the blog post, and I believe
there's some examples shipped with the gem. There needs to be more docs,
certainly, and hopefully they'll get some TLC soon.

Also, I forgot to call out Evan Phoenix for coming up with the API and
initial design, and he or someone else on Rubinus wrote up the
templating/header-file-processing stuff as well. And of course a huge
thanks to Wayne Meissner for implementing FFI not just once (for JRuby)
but twice (for C Ruby). His work will mean a huge leap forward in
cross-impl portability.

- Charlie

Radoslaw Bulat

11/1/2008 8:39:00 AM

0

T24gU2F0LCBOb3YgMSwgMjAwOCBhdCA2OjQwIEFNLCBDaGFybGVzIE9saXZlciBOdXR0ZXIKPGNo
YXJsZXMubnV0dGVyQHN1bi5jb20+IHdyb3RlOgo+IEFjdHVhbGx5IHN0cnVjdHMgYXJlIGFscmVh
ZHkgc3VwcG9ydGVkISBTZWUgdGhlIGJsb2cgcG9zdCwgYW5kIEkgYmVsaWV2ZQo+IHRoZXJlJ3Mg
c29tZSBleGFtcGxlcyBzaGlwcGVkIHdpdGggdGhlIGdlbS4KCllvdXIgYmxvZyBpcyBwcmVhdHkg
a25vd24gYnV0IGZvciBjbGFyaXR5OgpodHRwOi8vYmxvZy5oZWFkaXVzLmNvbS8yMDA4LzEwL2Zm
aS1mb3ItcnVieS1ub3ctYXZhaWxhYmxlLmh0bWwKOi0pCgotLSAKUmFkb3OzYXcgQnWzYXQKCmh0
dHA6Ly9yYWRhcmVrLmpvZ2dlci5wbCAtIG3zaiBibG9nCg==

Charles Oliver Nutter

11/1/2008 10:18:00 AM

0

RadosÅ?aw BuÅ?at wrote:
> On Sat, Nov 1, 2008 at 6:40 AM, Charles Oliver Nutter
> <charles.nutter@sun.com> wrote:
>> Actually structs are already supported! See the blog post, and I believe
>> there's some examples shipped with the gem.
>
> Your blog is preaty known but for clarity:
> http://blog.headius.com/2008/10/ffi-for-ruby-now-avai...
> :-)

Oh right, a link would have been useful. Thank you :)

- Charlie

Charles Oliver Nutter

11/1/2008 10:19:00 AM

0

Charles Oliver Nutter wrote:
> I posted a blog entry with a longer description of the library,
> additional examples, and links to some other documentation and posts.

And then I completely forgot to include the blog post URL...

http://blog.headius.com/2008/10/ffi-for-ruby-now-avai...

- Charlie

Luc Heinrich

11/1/2008 10:26:00 AM

0

On 1 nov. 08, at 11:19, Charles Oliver Nutter wrote:

> And then I completely forgot to include the blog post URL...

Looks cool, great work.

Two questions:

- Are variadic functions supported?
- Do you have any idea or measurements of the overhead of calling
through FFI as opposed to using a compiled extension?

--
Luc Heinrich - luc@honk-honk.com


Charles Oliver Nutter

11/1/2008 11:16:00 AM

0

Luc Heinrich wrote:
> On 1 nov. 08, at 11:19, Charles Oliver Nutter wrote:
>
>> And then I completely forgot to include the blog post URL...
>
> Looks cool, great work.
>
> Two questions:
>
> - Are variadic functions supported?
> - Do you have any idea or measurements of the overhead of calling
> through FFI as opposed to using a compiled extension?

Wayne answers the latter, sorta, on his followup blog post:

http://blog.headius.com/2008/10/ffi-for-ruby-now-avai...

He doesn't have specific numbers for performance at the moment, but the
short story is that FFI introduces a bit of overhead; ultimately I
believe that the overhead gets lost in the flow of a Ruby application,
especially when you're tossing units of work across like SQL queries or
arrays. Wayne probably can fill in more details on what the actual
overhead is like.

And I'd also expect that any small amount of overhead is vastly
outweighed by the ability to write an FFI-based library once and use it
across implementations.

- Charlie

Luc Heinrich

11/1/2008 9:25:00 PM

0

On 1 nov. 08, at 12:16, Charles Oliver Nutter wrote:

> He doesn't have specific numbers for performance at the moment, but
> the short story is that FFI introduces a bit of overhead; ultimately
> I believe that the overhead gets lost in the flow of a Ruby
> application, especially when you're tossing units of work across
> like SQL queries or arrays.

# --- [begin unscientific test] --------

require 'rubygems'
require 'benchmark'
require 'zlib'
require 'ffi'
require 'dl/import'

module Zlib_ffi
extend FFI::Library
attach_function :zlib_version, :zlibVersion, [], :string
end

module Zlib_dl
extend DL::Importable
dlload "libz.dylib"
extern "const char* zlibVersion()"
end

puts Zlib.zlib_version
puts Zlib_ffi.zlib_version
puts Zlib_dl.zlibVersion

Benchmark.bm(3) do |bm|
bm.report("ext") { 500_000.times { Zlib.zlib_version } }
bm.report("ffi") { 500_000.times { Zlib_ffi.zlib_version } }
bm.report("dl") { 500_000.times { Zlib_dl.zlibVersion } }
end

# --- [end unscientific test] --------

This gives the following results:

1.2.3
1.2.3
1.2.3
user system total real
ext 1.050000 0.320000 1.370000 ( 1.373800)
ffi 2.160000 0.660000 2.820000 ( 2.818966)
dl 3.500000 1.060000 4.560000 ( 4.552789)

All this using MacPorts MRI 1.8.7-p72 under OS X 10.5.5. The observed
overhead is slightly over 2x for ffi, probably not a big deal unless
ffi calls are used in tight loops I guess.


PS: haven't seen any trace of variadic function support in the code.

--
Luc Heinrich - luc@honk-honk.com


Radoslaw Bulat

11/1/2008 11:20:00 PM

0

V2hlcmUgY2FuIEkgZmlsZSBhbiBpc3N1ZT8gSSBoYXZlIHRyb3VibGUgdG8gYnVpbGQgaW4gd2l0
aCBydWJ5MS45IG9uIDY0Yml0LgoKLS0gClJhZG9zs2F3IEJ1s2F0CgpodHRwOi8vcmFkYXJlay5q
b2dnZXIucGwgLSBt82ogYmxvZwo=

Radoslaw Bulat

11/1/2008 11:23:00 PM

0

PiBUaGlzIGdpdmVzIHRoZSBmb2xsb3dpbmcgcmVzdWx0czoKPgo+IDEuMi4zCj4gMS4yLjMKPiAx
LjIuMwo+ICAgICAgICAgdXNlciAgICAgc3lzdGVtICAgICAgdG90YWwgICAgICAgIHJlYWwKPiBl
eHQgIDEuMDUwMDAwICAgMC4zMjAwMDAgICAxLjM3MDAwMCAoICAxLjM3MzgwMCkKPiBmZmkgIDIu
MTYwMDAwICAgMC42NjAwMDAgICAyLjgyMDAwMCAoICAyLjgxODk2NikKPiBkbCAgIDMuNTAwMDAw
ICAgMS4wNjAwMDAgICA0LjU2MDAwMCAoICA0LjU1Mjc4OSkKPgoKVWJ1bnR1IDguMTAgNjRiaXQK
CiQgcnVieSAtLXZlcnNpb24gJiYgcnVieSBmZmlfYmVuY2gucmIKcnVieSAxLjguNyAoMjAwOC0w
OC0xMSBwYXRjaGxldmVsIDcyKSBbeDg2XzY0LWxpbnV4XQoxLjIuMy4zCjEuMi4zLjMKMS4yLjMu
MwogICAgICAgICB1c2VyICAgICBzeXN0ZW0gICAgICB0b3RhbCAgICAgICAgcmVhbApleHQgIDAu
MzIwMDAwICAgMC4wNzAwMDAgICAwLjM5MDAwMCAoICAwLjM5Njc3NCkKZmZpICAwLjc3MDAwMCAg
IDAuMTIwMDAwICAgMC44OTAwMDAgKCAgMC44OTUwOTMpCmRsICAgMi4wOTAwMDAgICAwLjI3MDAw
MCAgIDIuMzYwMDAwICggIDIuMzY1MDI5KQoKCgoKLS0gClJhZG9zs2F3IEJ1s2F0CgpodHRwOi8v
cmFkYXJlay5qb2dnZXIucGwgLSBt82ogYmxvZwo=