From: Alex Fenton Date: 2009-05-07T20:15:03+09:00 Subject: Re: storing c pointers in ruby hash Rolando Abarca wrote: >> I'm been banging my head on the keyboard the whole day trying to >> track a bug. You probably should post more information about what happens when the bug hits: eg is it a rb_bug, and if so, with what message? Can you provide a gdb backtrace of the C call stack? >> The idea is to keep a reference to the ruby counterpart of the Obj-C >> object. Right now, I'm using a "global" hash table, defined as this: ... The code looks ok from a casual look, though I'm not sure INT2FIX is the right conversion macro to use. SWIG does this to create a conversion macro (SWIG2NUM) for making Ruby hash keys from pointers. /* Ruby 1.8 actually assumes the first case. */ #if SIZEOF_VOIDP == SIZEOF_LONG # define SWIG2NUM(v) LONG2NUM((unsigned long)v) # define NUM2SWIG(x) (unsigned long)NUM2LONG(x) #elif SIZEOF_VOIDP == SIZEOF_LONG_LONG # define SWIG2NUM(v) LL2NUM((unsigned long long)v) # define NUM2SWIG(x) (unsigned long long)NUM2LL(x) #else # error sizeof(void*) is not the same as long or long long #endif >> The thing is, that the rb_obj is crashing the ruby interpreter. If I >> try to call any method on it (even inspect) I get a bad access >> error. It was working with a ruby 1.8 version, but now that I've >> ruby 1.9, it refuses to work... Any idea of what I could be doing >> wrong here? If above doesn't help, what version of 1.8 were you using previously? If < 1.8.7 then you might see if the bug is "object allocation during garbage collection". The size of pointers on Mac OS X mean that when they are converted to ruby Numerics, they may be BigNums. These are not immediate objects and involve allocation; if you happen to do this during GC it's a mistake. Ruby 1.8.6 and earlier were indulgent to this failing, but 1.8.7 and 1.9.1 are not. You could test this by placing GC.disable at the very start of your script and seeing if the crash still happens. >> Is there a better way to link a ruby object with a c pointer? I need >> to get the associated ruby object to a given objc object. Do you have an alternate hash map implementation available, eg from ObjC standard libraries? Can you use this instead to create a straight pointer->VALUE map? I would try this as using Ruby Hash adds unnecessary complexity involved with converting the pointer keys to VALUE, and GC. Several of the things you appear to be trying to do (have a persistent ObjC -> Ruby object link; forward method calls from ObjC to Ruby) are similar to what SWIG provides for C++ and you might find it useful to look at the implementation of "object tracking" and "directors"/"cross-language polymorphism" there. The former uses a hash, the latter uses a C++ class which multiply inherits from the wrapped C++ class and a simple C++ class called "Director" which has the VALUE as member, and forwards method calls to rb_funcall on that VALUE. hth alex