MRI 和 Rubinius 支持 Ruby 的本地扩展,这使得本地代码可以与 Ruby 代码及 Ruby 解释器或 VM 进行交互。 Ruby 1.8.0 引入了 Ruby/DL ,它可以加载共享库并调用 Ruby 代码中提供的函数。 Ruby/DL 文档说明了如何导入函数、如何与 C 类型协同工作及如何将 Ruby 映射为 C 类型等等。Ruby/DL 还提供了两种回调方式,也就是说对于一个接收函数指针的 C 函数来说,我们可以将一个 Ruby 代码块传进去。
Rubinius 引入了自己的 Foreign Function Interface(FFI),它与 Ruby/DL 非常像,尽管 FFI 的 API 看起来有些不同,对于类型签名来说,它使用了 Ruby 符号和排列方式而并没有采取 C 代码的方式,也没有使用 Ruby/DL 中所用的客户化类型格式。
早在今年初,构建于 JNA 之上的 jruby-ffi 就已经发布了(JRuby 不支持 Ruby/DL)。
虽然对 Rubinius 和 JRuby 提供了支持,但在使用 MRI 的 Ruby 世界中还是有很多地方依然在使用 Ruby/DL 或其它方式来使用共享库。为了解决这个问题, Wayne Meissner (已经创建了 jruby-ffi)创建了 ruby-ffi 项目,它现在提供了相同的 FFI 接口,就像 Rubinius 之于 JRuby、Ruby 1.8.x 及 Ruby 1.9.x. 一样。通过 ruby-ffi,我们可以跨越所有这些 Ruby 实现以相同的 Ruby 代码来访问共享库了。
Ruby FFI 0.2.0 已经发布了,可以通过 gem install ffi 进行安装。你可以在其项目的wiki 上查看相关的文档,这些示例是很好的入门材料。 Charles Nutter 对 FFI 的使用进行了更详尽的说明并给出了一些例子。
评论