From: "Matthew S." Date: 2011-12-05T04:25:56+09:00 Subject: [Ruby C] Using DATA_PTR in multiple methods I'm writing a Ruby extension in C to utilize a library (tsk3, aka. The Sleuth Kit) for opening disk images, and I found I couldn't get Data_Get_Struct to return the Struct built during initialization. This seemed odd as I built my class "by the book", and could get data from inside the Struct during initialization. The only workaround I found was referring to DATA_PTR directly (see code below), which is odd because I found few examples of this in the community. I thought the whole point of Data_Get_Struct(self, C TYPE, ptr) was to fetch the Struct wrapped by 'self' and return a reference (ptr) to it. I'm developing on 1.8.7, but will be moving on to 1.9 soon, and would like to know if I'm about to make a major mistake by using what looks like an old workaround. Why would VALUE self not be sufficient for Ruby to fetch the Struct using the Data_Get_Struct macro? Is assigning DATA_PTR(self) to the C pointer going to wreck the ruby Object being created? #include #include #include // prototypes static VALUE rb_mtsk4r; static VALUE rb_cClass1; static VALUE initialize(VALUE self); static VALUE sector_size(VALUE self); VALUE klass; // alloc & dealloc static void deallocate(void * image){ xfree((TSK_IMG_INFO *)image); } static VALUE allocate(VALUE klass){ TSK_IMG_INFO *ptr; return Data_Make_Struct(klass, TSK_IMG_INFO, 0, xfree, ptr); } // init a FirstClass (Image) object VALUE initialize(VALUE self){ char * filename; filename = "/tmp/test.image"; TSK_IMG_INFO *image; // declare inner struct Data_Get_Struct(self, TSK_IMG_INFO, image); // fetch inner struct from self // use function from libtsk3 to open disk image image = tsk_img_open_sing(filename, TSK_IMG_TYPE_DETECT, 0); fprintf(stdout, "image size: %d\tsector size:%d\n", (int)image->size, (int)image->sector_size); Check_Type(self, T_DATA); // done fprintf(stdout, "DATA_PTR(self): %lu\n", (long)DATA_PTR(self)); DATA_PTR(self) = image; // Not sure I should be doing this... fprintf(stdout, "DATA_PTR(self): %lu\n", (long)DATA_PTR(self)); return self; } static VALUE sector_size(VALUE self){ TSK_IMG_INFO * image; Data_Get_Struct(self, TSK_IMG_INFO, image); return INT2NUM(image->sector_size); } void Init_tsk4r() { rb_mtsk4r = rb_define_module("TSK"); // class definition rb_cClass1 = rb_define_class_under(rb_mtsk4r, "Image", rb_cObject); // allocation function rb_define_alloc_func(rb_cClass1, allocate); // object methods rb_define_method(rb_cClass1, "initialize", initialize, 0); rb_define_method(rb_cClass1, "sector_size", sector_size, 0); } -- Posted via http://www.ruby-forum.com/.