From: "Iñaki Baz Castillo" Date: 2012-05-18T00:07:25+09:00 Subject: rb_gc_register_address() or rb_gc_mark()? Hi, I've bad experiences with rb_gc_register_address(), it does never work for me so I end using Ruby hashes and so. Well, for my Ruby class defined in C I set a "alloc" method in which I malloc and wrap a C struct: ------------------------------------ struct my_cdata { int active; uv_udp_t *uv_handle; } VALUE MyClass_alloc(VALUE klass) { // Fill C struct: struct my_cdata *cdata = ALLOC(struct my_cdata); cdata->active = 0; cdata->uv_handle = ALLOC(uv_udp_t); // Get the created MyClass instance: VALUE instance = Data_Wrap_Struct(klass, NULL, MyClass_free, cdata); // Store the instance within the uv_handle->data field: cdata->uv_handle->data = instace; return instance; } ----------------------------------------- When the UV UDP handle object receive data, UV async library calls a callback passin gthe UV UDP handle, so in that callback I need to retrieve the Ruby MyClass instance from the uv_handle: VALUE instance = uv_handle->data; // Run the Ruby callback and so... rb_funcall(instance, xxxxxx, xxxxxx, xxxxxx); Assuming that the created MyClass instance is not referenced in Ruby land (it's not in a hash, array, variable...) then this code would crash since probably GC has freed "instance". So there are (or could be) 3 solutions: 1) Storing the instance in a Ruby hash (and yes, it works, but it's ugly). 2) In the MyClass_alloc() function, before the "return" add: rb_gc_register_address(&instance); But this DOES NOT work for me, I get segmentfauls ! 3) Setting a mark function in Data_Wrap_Struct, and within such a mark function do: rb_gc_mark(uv_handle->data); I've read point 3 in this thread: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/147514 So, is the choice 2 wrong and choice 3 is correct? Thanks a lot. -- Iñaki Baz Castillo