最近需要用到 Ruby 和 C 交互,把 C 调用 Ruby 记录下来了。写了一个简单的示例,演示一下如何使用 C 调用 Ruby,我的环境是 macOS 上面,使用 Xcode 创建的一个 demo。
工程目录下面一个 ruby.rb 文件:
module BoxModule
class Box
def initialize(w, h)
@width, @height = w, h
puts "Box widht is : #@width"
puts "Box height is : #@height"
end
# set 方法
def setWidth(value)
@width = value
end
def setHeight(value)
@height = value
end
# get 方法
def getWidth()
@width
end
def getHeight()
@height
end
# 打印测试
def printArea
# puts getWidht() * getHeight()
@area = getWidth() * getHeight()
puts "Box area is : #@area"
end
def printABC(value)
# @val = value
# puts "ABC value is : #@val"
puts "ABC value is : #{value}"
end
end
end
main.m 里面首先需要导入 :
#import <Ruby/ruby.h>
main.m 实现如下:
// 获取 ruby.rb 目录
NSString *rubyPath = [[NSBundle mainBundle] pathForResource:@"ruby" ofType:@"rb"];
// 构造 VM,如果初始化发生错误,返回一个非零值
if (ruby_setup())
{
NSLog(@"Failed to init Ruby VM");
return;
}
// 导入 ruby 文件
rb_require([rubyPath UTF8String]);
// 执行 BoxModule 模块 Box 类的 new() 方法,创建一个对象
VALUE box = rb_eval_string("BoxModule::Box.new(3, 5)");
// 调用 ruby 函数,第一个参数为创建的对象,第二个参数为函数 id,第三个参数为函数参数个数,后面参数为传入参数值
rb_funcall(box, rb_intern("setWidth"), 1, rb_int_new(30));
rb_funcall(box, rb_intern("setHeight"), 1, rb_int_new(5));
rb_funcall(box, rb_intern("printArea"), 0);
rb_funcall(box, rb_intern("printABC"), 1, rb_str_new("abc", 3));
rb_funcall(box, rb_intern("printABC"), 1, rb_str_new2("cba"));
rb_funcall(box, rb_intern("printABC"), 1, rb_int_new(123));
// 销毁 VM,如果清理失败,返回一个非零值
ruby_cleanup(0);
运行结果:
Box widht is : 3
Box height is : 5
Box area is : 150
ABC value is : abc
ABC value is : cba
ABC value is : 123
相关概念性说明,可以参考我下面给出来的参考文档。
参考文档:
Running Ruby in C