编写内联 C - RubyInLine
RubyInline 是一个框架,允许你在 Ruby 代码中嵌入其他语言。它定义了 Module#inline 方法,该方法返回一个构建器对象。你将构建器传递给包含用 Ruby 之外的语言编写的代码的字符串,然后构建器将其转换为可以从 Ruby 调用的内容。
当给定 C 或 C++代码(默认 RubyInline 安装中支持的两种语言)时,构建器对象会将一个小扩展名写入磁盘,编译并加载它。你不必自己处理编译,但可以在主目录的 .ruby_inline 子目录中看到生成的代码和已编译的扩展。
在 Ruby 程序中嵌入 C 代码:
- RubyInline(作为 rubyinline gem 提供)自动创建扩展
RubyInline 不能在 irb 中工作
#!/usr/bin/ruby -w
# copy.rb
require 'rubygems'
require 'inline'
class Copier
inline do |builder|
builder.c <<END
void copy_file(const char *source, const char *dest)
{
FILE *source_f = fopen(source, "r");
if (!source_f)
{
rb_raise(rb_eIOError, "Could not open source : '%s'", source);
}
FILE *dest_f = fopen(dest, "w+");
if (!dest_f)
{
rb_raise(rb_eIOError, "Could not open destination : '%s'", dest);
}
char buffer[1024];
int nread = fread(buffer, 1, 1024, source_f);
while (nread > 0)
{
fwrite(buffer, 1, nread, dest_f);
nread = fread(buffer, 1, 1024, source_f);
}
}
END
end
end
C 函数 copy_file
现在作为 Copier
的实例方法存在:
open('source.txt', 'w') { |f| f << 'Some text.' }
Copier.new.copy_file('source.txt', 'dest.txt')
puts open('dest.txt') { |f| f.read }