Ruby FFI - Ruby调用C库最棒的工具

转载 2012年03月22日 23:24:19

Ruby FFI - Ruby调用C库最棒的工具

2008-11-02 00:40 by 见习编辑 robbin 评论(6) 有4162人浏览
Ruby C++ C C#
Ruby解析器的性能一向被人垢病,很多性能敏感的程序,都必须用C语言来编写,然后使用Ruby去调用C库。但糟糕的是,Ruby调用C库并不是一件轻松的活,需要你对Ruby的内部数据结构有比较深入的了解,甚至需要你仔细阅读Ruby相关的源代码,然后用C语言编程作为黏合剂,用Ruby特有的C API去给外部的C库增加一层封装。 

以上的过程,相当于你要打开Ruby解析器的内部进行API调用了,对程序员的要求很高。而且一旦Ruby内部的数据结构随着版本升级发生变动,你的这些黏合剂程序就必须重写。比方说现在Ruby 1.9出来以后,绝大部分Ruby的C扩展库统统无法正常编译。 

基于以上这些原因,给Ruby写C的扩展库一件非常痛苦的事情,而且也是Ruby社区程序员一直抱怨的问题之一。然而随着FFI的出现,我们即将告别这些痛苦的历史! 

FFI即Foreign Function Interface,外部函数调用接口,并非Ruby独有的概念,只不过因为Ruby扩展库带来的痛苦,使得Ruby的FFI显得格外迫切。FFI最早已经在Rubinius虚拟机平台上实现了,随后在JRuby上面也得以实现,而今天:2008年11月1日,在Ruby官方版本的解析器Ruby 1.8.6/1.8.7和1.9版本上也可以使用FFI了。 

安装FFI很简单: 

Ruby代码 
  1. gem install ffi  


使用FFI也很简单,比方说调用C语言标准库的printf函数,我们可以这样来写: 

Ruby代码 
  1. require 'ffi'  
  2. module MyExtModule  
  3.   extend FFI::Library  
  4.   attach_function :printf, [:string], :void  
  5. end  
  6.   
  7. MyExtModule.printf("Hello FFI\n")  


用attach_fuction就可以把C语言标准库的printf函数绑定到ruby里面来了,后面的参数分别声明C函数的传入参数和返回值。如果需要引入其他C库,可以预先使用ffi_lib指定库的名称。(我使用ffi_lib未能绑定非标准库,有可能是FFI的bug?也有可能是我没有设置对?) 

有了FFI,在Ruby语言里面调用C库,就变成了一件异常轻松的事情,完全不需要ruby程序员再去吭哧吭哧啃C语言了,只要你手里捧着C库的API手册能看清楚函数的参数定义就够用了,然后你就可以直接在ruby里面随心所欲的调用它了,在调用之前,只需要用attach_function进行一次函数绑定声明即可。这对于整个ruby社区来说是一件非常棒的好消息。 

在FFI的源代码树的samples目录下面还有几个小例子,大家可以自己看看:http://kenai.com/projects/ruby-ffi/sources/723/show 

作为一个对比,我们来看看传统的ruby扩展库是如何调用C库的吧。以上面的为例,如果我们希望在ruby里面使用C库的printf函数,那么要先用ruby API的格式来写一段C代码去封装它: 

C代码 
  1. #include <ruby.h>  
  2.    
  3. static VALUE  
  4. dummy_printf(VALUE self, VALUE format, VALUE num)  
  5. {  
  6.     int rlt = printf(RSTRING_PTR(format), NUM2INT(num));  
  7.     return INT2FIX(rlt);  
  8. }  
  9.    
  10. void Init_printf()  
  11. {  
  12.     /* register the method to the Kernel module */  
  13.     rb_define_method(rb_mKernel, "dummy_printf",  
  14.                      RUBY_METHOD_FUNC(dummy_printf), 2);  
  15. }  


当然你必须对ruby.h里面定义的ruby内部数据结构和ruby内部的函数调用有充分的了解。然后你要创建一个extconf.rb文件: 

Ruby代码 
  1. require 'mkmf'   
  2. create_makefile('printf')  


运行这个文件:ruby extconf.rb,会创建出来编译这段C代码的Makefile,然后你再编译和安装,最终这个共享链接库会被拷贝到你的ruby的本地扩展库目录下面。最后你才可以在ruby里面调用这个封装好的dummy_printf方法。 

另外,对于通过FFI去调用比较复杂的C库的时候,会涉及到不同语言之间的数据类型转换问题,关于数据类型的对照表,以及FFI使用更详细的介绍请看张驰原(他也是rmmseg的作者)的文章:http://pluskid.lifegoo.com/?p=370 

相关文章推荐

Ruby-FFI 1.1.5

  • 2012年09月11日 14:22
  • 14KB
  • 下载

ruby on rails -使用scaffold的CRUD

ruby on rails — scaffold scaffold 脚手架是rails非常省事的方法,实现一些简单的增删改查. CRUD 增删改查 1. 创建rails项目 $ rail...

Ruby-元编程和自定义访问器attr_accessor

Ruby中自定义访问器attr_accessor_with_history

Ruby-自定义迭代器与yield方法

自定义迭代器each_with_custom_index和浅显的理解关于yield方法

Ruby on Rails,rake工具使用和数据库migrations迁移的概念

欢迎来我的博客http://blog.csdn.net/abbuggy/article/details/7648920 《Ruby on Rails,一个简单的CMS系统,创建应用骨架并与数据库...
  • ABBuggy
  • ABBuggy
  • 2012年06月09日 22:41
  • 6134

一个python程序员的ruby三日游(三)——构建工具

rakefilemakefilesconsrubyrake 目录(?)[+] 在构建上,Ruby比Python会强大些。 Ruby用的是Rake,Python兴许是scons,如果是用于...

Ruby开发者应该熟悉的10个工具

1. Git Git 是进入Ruby 这个生态圈首先最应该学会的工具。几乎所有以Ruby 开发出来的套件都放在Github 上。也就是不管你要下载或修改协作都需要透过Git。 2. RVM...
  • rocLv
  • rocLv
  • 2011年11月28日 16:28
  • 473

Ruby开发者应该熟悉的10个工具

1. Git Git 是进入Ruby 这个生态圈首先最应该学会的工具。几乎所有以Ruby 开发出来的套件都放在Github 上。也就是不管你要下载或修改协作都需要透过Git。 2. RVM...
  • rocLv
  • rocLv
  • 2014年05月08日 08:29
  • 384

七、Sketchup用ruby进行二次开发--利用Transformation实现Move工具(平移、旋转和缩放)

在Sketchup中,move工具使用的非常广泛,

Ruby On Rails中REST API使用示例——基于云平台+云服务打造自己的在线翻译工具

做为一个程序员可能在学习技术,了解行业新动态,解决问题时经常需要阅读英文的内容;而像我这样的英文小白就只能借助翻译工具才能理解个大概;不禁经常感慨,英文对学习计算机相关知识太重要了!最近发现IBM的云...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Ruby FFI - Ruby调用C库最棒的工具
举报原因:
原因补充:

(最多只允许输入30个字)