跳转至内容

Ruby 编程/C 扩展

来自 Wikibooks,开放世界中的开放书籍

使用 C 扩展扩展 ruby 相对容易。包含在 ruby 源代码中的 README.EXT 文件 非常有用,它讨论了创建 ruby 扩展,以及在 ruby 和 c 类型之间进行转换。

通常,C 扩展看起来像这样

文件 go.c

#include "ruby.h"

void Init_go() {

}

然后,您可以使用 mkmf 库为其创建一个 Makefile。


扩展配置文件

[编辑 | 编辑源代码]

此文件使用 mkmf 库创建 Makefile。然后,Makefile 与 make 程序一起使用来创建扩展。

一个简单的配置文件如下所示

文件 config.rb

require "mkmf"

# the string is the init function's suffix in the .c source file. e.g, void Init_go()
# it's also the name of the extension. e.g, go.so
create_makefile("go")

创建扩展的过程

[编辑 | 编辑源代码]

这是一个简单的扩展的简要概述,它打印经典短语“Hello!”。如果您想创建更有用的东西,则需要了解 C 并阅读 README.EXT 文件。

创建一个新文件夹并将下面的两个文件添加到其中。

文件 hello.c

#include <ruby.h>
VALUE hello(VALUE self);

void Init_hello() {
  rb_define_global_function("hello", hello, 0);
}

VALUE hello(VALUE self)
{
  printf("Hello!\n");

  return Qnil;
}

文件 config.rb

require 'mkmf';

# extension name
extname = 'hello';

create_makefile(extname);

现在,从命令提示符运行以下命令

ruby config.rb
make (replace with "nmake" for Windows SDK)

现在进行测试。键入以下内容以加载扩展。

irb -r .\hello.so

输入“hello”,IRB 将回显。

irb(main):002:0>hello
Hello!
=> nil

1.9 和 1.8 之间的区别

[编辑 | 编辑源代码]

1.9 至少在定义了更多宏方面存在差异。以下是在 1.8 中获取它们的方法(其中一些来自 Phusion Passenger 的代码)。

#ifndef RARRAY_LEN
	#define RARRAY_LEN(ary) RARRAY(ary)->len
#endif
#ifndef RSTRING_PTR
	#define RSTRING_PTR(str) RSTRING(str)->ptr
#endif
#ifndef RSTRING_LEN
	#define RSTRING_LEN(str) RSTRING(str)->len
#endif

#ifndef RBIGNUM_DIGITS
    #define RBIGNUM_DIGITS(obj) RBIGNUM(obj)->digits
#endif

JRuby 中的 C 扩展

[编辑 | 编辑源代码]

您可以在 jruby 中使用 java 扩展(显然)。您还可以使用 ffi 和/或 ffi-inliner gem 来使用本地 C 扩展。

[编辑 | 编辑源代码]

一个教程

华夏公益教科书