Peter Schrammel wrote: >(...) > I'd like to implement this as an extension so the testcode should look > like this: It may help if you explain what your trying to do a bit more. > > #!/usr/bin/ruby > require("RFuse") > > class RFuse > def getdir(path,filler) > Dir.foreach(path) {|x| filler.push(x,8)} > end > def getattr(path) > end > end > > fo=RFuse.new > begin > fo.main > rescue > f=File.new("/tmp/error","w+") > f.puts "Error:" + $! > f.close > end > > The user should just extend the class with some methods which will be > called back by fuse. So I have to wrap the callbacks. The interesting > line is at ***. > > #ifdef linux > /* For pread()/pwrite() */ > #define _XOPEN_SOURCE 500 > #endif > //FOR LINUX ONLY > #include <linux/stat.h> > > #include <ruby.h> > #include <fuse.h> > #include <errno.h> > #include <sys/statfs.h> > #ifdef HAVE_SETXATTR > #include <sys/xattr.h> > #endif > > > //This is a wrapper around the filler callback function > struct fill_t { > fuse_dirfil_t filler; > fuse_dirh_t handler; > }; > the function below should be registered using rb_define_alloc_func() and is typically called rfill_alloc() > static VALUE rfill_new(VALUE class){ > VALUE self; > struct fill_t *filler; > self = Data_Make_Struct(class, struct fill_t, 0,free,filler); > return self; > } > > static VALUE rfill_push(VALUE self,VALUE name, VALUE type) { > struct fill_t *fill; > Data_Get_Struct(self,struct fill_t,fill); > fill->filler(fill->handler,STR2CSTR(name),NUM2INT(type)); > return self; > } > > //------------------ > > > static VALUE global_self; //TODO: have to avoid global vars > > //call getdir with that an RFiller object > static int rf_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t f) > { > VALUE rfiller_class; > VALUE rfiller_instance; > struct fill_t *fillerc; > rfiller_class=rb_const_get(rb_cObject,rb_intern("RFiller")); > > //***the following line seems to be the problem. If I comment everything > out between here and "return 0" it runs okay... though nothing happens. > *** see above *** > rfiller_instance=rb_funcall(rfiller_class,rb_intern("new"),0); > //BTW: I can't do the rb_class_new_instance here STRANGE! > > //***commenting out from here gives me strange errors (see bellow) > you don't need this, if your worried about rfiller_instance being GC'ed make it volatile. > rb_gc_register_address(&rfiller_instance);//Do I need this? > Data_Get_Struct(rfiller_instance,struct fill_t,fillerc); > fillerc->filler=f;//Init the filler by hand....not nice... > fillerc->handler=h; not sure how the flow of control goes in your program but seems pretty obvious you have infinite recursion going on right here. > rb_funcall(global_self,rb_intern("getdir"),2,rb_str_new2(path),rfiller_instance); > don't need this either > //destroy the filler... > rb_gc_unregister_address(&rfiller_instance); > return 0; > } > (...) > > void Init_RFuse() { > VALUE cRFuse=rb_define_class("RFuse",rb_cObject); should be using rb_define_alloc_func() as noted above > rb_define_singleton_method(cRFuse,"new",rf_new,0); > rb_define_method(cRFuse,"initialize",rf_init,0); > rb_define_method(cRFuse,"main",rf_main,0); > > VALUE cRFiller=rb_define_class("RFiller",rb_cObject); '' > rb_define_singleton_method(cRFiller,"new",rfill_new,0); > //rb_define_method(cRFiller,"initialize",rfill_init,0); > rb_define_method(cRFiller,"push",rfill_push,2); > // rb_define_method(cRFiller,"test",rfill_test,0); > } > (...) -Charlie