本章主要介绍 Ruby Object 与C++对象绑定
//============================================================================
// Name : RubyCPP.cpp
// Author : frodo
//============================================================================
#include <iostream>
#include <ruby.h>
using namespace std;
VALUE rb_print_value(VALUE obj){
VALUE str = rb_obj_as_string(rb_inspect(obj));
printf("%s\n", StringValueCStr(str));
return Qnil;
}
VALUE rb_ext_p(int argc, VALUE* argv, VALUE thiz){
int i;
VALUE ret = Qnil;
for (i = 0; i < argc; i++) {
rb_print_value(argv[i]);
}
if (argc == 1) {
ret = argv[0];
} else if (argc > 1) {
ret = rb_ary_new4(argc, argv);
}
if (TYPE(rb_stdout) == T_FILE) {
rb_io_flush(rb_stdout);
}
return ret;
}
class A{
public:
int v;
public:
static A* create(){
A* a = new A();
return a;
}
void init(int _v){
this->v = _v;
}
};
void wrap_A_free (A* ptr)
{
ruby_xfree(ptr);
}
VALUE wrap_A_allocate (VALUE self)
{
void* p = A::create();
return Data_Wrap_Struct (self, NULL, wrap_A_free, p);
}
VALUE rb_A_v(VALUE self){
A* a = NULL;
Data_Get_Struct(self, A, a);
printf("%d\n", a->v);
return Qnil;
}
VALUE rb_A_initialize(int argc, VALUE* argv, VALUE self){
int v = FIX2INT(argv[0]);
A* a = NULL;
Data_Get_Struct(self, A, a);
a->init(v);
return Qnil;
}
void initExtKreal(){
rb_define_global_function("p", RUBY_METHOD_FUNC(rb_ext_p), -1);
VALUE klassA = rb_define_class("A", rb_cObject);
rb_define_alloc_func(klassA, wrap_A_allocate);
rb_define_method(klassA, "v", RUBY_METHOD_FUNC(rb_A_v), 0);
rb_define_method(klassA, "initialize", RUBY_METHOD_FUNC(rb_A_initialize), -1);
}
int main() {
ruby_init();
ruby_init_loadpath();
ruby_script("ruby-android");
initExtKreal();
int ret = 0;
rb_eval_string_protect(
"class A;"
"end;"
"a = A.new(100);"
"a.v;"
"a = nil;"
, &ret);;
rb_eval_string_protect(
"GC.start;"
, &ret);;
rb_p(rb_errinfo());
return 0;
}
绑定最基本的就是
Data_Wrap_Struct 包围一个数据到对象
和
Data_Get_Struct 从对象获取绑定数据
这2个函数了。
这个函数能够绑定 一个对象的数据。
然后还有一个就是
void rb_define_alloc_func(VALUE, rb_alloc_func_t);
这个函数了
主要相应的就是 一个Ruby 对象的物理内存声请和 释放。
第一个參数是 要绑定的对象, 通常是 rb_define_class 的返回值。
第二个就是一个函数指针。
在这个对象被 new 的时候 就会进到这里。我们能够在这里做物理的内存声请。
可是我这样写有个弊端。
就是參数无法传递进来。
做法是重定义 initialize 方法。 假设熟悉ruby 就应该知道这个是 一个对象是new后调用的,參数也在这里传递。
測试OK :)