I am trying to make a Ruby module using the C API. I must admit, I am having trouble fully understanding the documentation online for it, but I am trying to return a Ruby Object using data from a C Structure from another class method (sorry if that doesn't make sense). Here is an example of my problem:
example.c
#include "ruby.h"
#include "extconf.h"
typedef struct example1_t
{
int x;
} example1_t;
typedef struct example2_t
{
char *name;
} example2_t;
void example1_free(example1_t *e1);
void example2_free(example2_t *e2);
static VALUE rb_example1_alloc(VALUE klass)
{
return Data_Wrap_Struct(klass, NULL, example1_free, ruby_xmalloc(sizeof(example1_t)));
}
static VALUE rb_example1_init(VALUE self, VALUE x)
{
example1_t *e1;
Check_Type(x, T_FIXNUM);
Data_Get_Struct(self, example1_t, e1);
e1->x = NUM2INT(x);
return self;
}
static VALUE rb_example1_x(VALUE self)
{
example1_t *e1;
Data_Get_Struct(self, example1_t, e1);
return INT2NUM(e1->x);
}
static VALUE rb_example2_alloc(VALUE klass)
{
return Data_Wrap_Struct(klass, NULL, example2_free, ruby_xmalloc(sizeof(example2_t)));
}
static VALUE rb_example2_init(VALUE self, VALUE s)
{
example2_t *e2;
Check_Type(s, T_STRING);
Data_Get_Struct(self, example2_t, e2);
e2->name = (char*)malloc(RSTRING_LEN(s) + 1);
memcpy(e2->name, StringValuePtr(s), RSTRING_LEN(s) + 1);
return self;
}
static VALUE rb_example2_name(VALUE self)
{
example2_t *e2;
Data_Get_Struct(self, example2_t, e2);
return rb_str_new_cstr(e2->name);
}
static VALUE rb_example2_name_len(VALUE self)
{
example1_t *len;
example2_t *e2;
Data_Get_Struct(self, example2_t, e2);
len->x = strlen(e2->name);
/*
How do I make a new Example1 Ruby Class from the "len"
structure and return it with the length of e2->name
assigned to len->x?
*/
return it?
}
void Init_example()
{
VALUE mod = rb_define_module("Example");
VALUE example1_class = rb_define_class_under(mod, "Example1", rb_cObject);
VALUE example2_class = rb_define_class_under(mod, "Example2", rb_cObject);
rb_define_alloc_func(example1_class, rb_example1_alloc);
rb_define_alloc_func(example2_class, rb_example2_alloc);
rb_define_method(example1_class, "initialize", rb_example1_init, 1);
rb_define_method(example1_class, "x", rb_example1_x, 0);
rb_define_method(example2_class, "initialize", rb_example2_init, 1);
rb_define_method(example2_class, "name", rb_example2_name, 0);
rb_define_method(example2_class, "name_len", rb_example2_name_len, 0);
}
void example1_free(example1_t *e1)
{
memset(e1, 0, sizeof(example1_t));
}
void example2_free(example2_t *e2)
{
memset(e2, 0, sizeof(example2_t));
}
As you can see in the rb_example2_name_len, I would like to create an Example1 class and return that from an Example2 method. How would I be able to do this?
Any help is much appreciated.