From: Peter Zotov Date: 2009-06-14T22:41:00+09:00 Subject: Re: C extension: VALUEs being collected too early eden li wrote: > I'm writing a C extension which passes around structs that refer to > Ruby VALUEs. During the course of execution, these VALUEs are > assigned new Ruby strings, hashes or arrays (via the rb_{str,hash,ary) > _new functions) through a series of callbacks. The problem is that it > seems they're getting collected too early before I have a chance to > use the result. > > I tried a few things to keep these VALUEs around (including calling > rb_gc_mark directly on these objects), but the only thing that seems > to prevent this early collection is by disabling the GC while my code > is executing. > > Is there something I can use to prevent these VALUEs from getting re- > used without resorting to turning off the GC altogether? > > Here's some pseudo code to help further illustrate the issue: > > typedef struct { > VALUE value; > // some other fields > } MyStruct; > > typedef struct { > MyStruct **structs; > } MyOtherStruct; > > VALUE my_rb_func(VALUE self) { > MyOtherStruct *other; > Data_Get_Struct(rb_iv_get(self, "@other"), MyOtherStruct, other); > other->structs[0]->value = rb_hash_new(); > > // This chain will allocate new MyStruct references and assign > // new Ruby objects to MyStruct->value entries. The rb_hash_new() > // won't be affected other than using rb_hash_aset(). > start_callback_chain(other); > > // without disabling gc, other->structs[0]->value is *not* the > original > // hash this is true even if we don't assign anything to subsequent > // MyStruct->value > } > Why do not use ruby array (rb_array_new) as MyOtherStruct? This may help (just need to keep one object instead of bunch of them...) -- WBR, Peter Zotov