Support object tracking. Updated SWIG_NewPointerObj and SWIG_Ruby_ConvertPtr to take into account object tracking.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7495 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Charlie Savage 2005-09-23 18:03:05 +00:00
commit 0316580de7

View file

@ -62,15 +62,26 @@ SWIG_Ruby_define_class(swig_type_info *type)
/* Create a new pointer object */ /* Create a new pointer object */
static VALUE static VALUE
SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int own) SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags)
{ {
int own = flags & SWIG_POINTER_OWN;
int track = flags & SWIG_TRACK_OBJECTS;
char *klass_name; char *klass_name;
swig_class *sklass; swig_class *sklass;
VALUE klass; VALUE klass;
VALUE obj; VALUE obj;
if (!ptr) if (!ptr)
return Qnil; return Qnil;
/* Have we already wrapped this pointer? */
if (track) {
obj = SWIG_RubyInstanceFor(ptr);
if (obj != Qnil) {
return obj;
}
}
if (type->clientdata) { if (type->clientdata) {
sklass = (swig_class *) type->clientdata; sklass = (swig_class *) type->clientdata;
@ -83,6 +94,12 @@ SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int own)
obj = Data_Wrap_Struct(klass, 0, 0, ptr); obj = Data_Wrap_Struct(klass, 0, 0, ptr);
} }
rb_iv_set(obj, "__swigtype__", rb_str_new2(type->name)); rb_iv_set(obj, "__swigtype__", rb_str_new2(type->name));
/* Keep track of this object if necessary */
if (track) {
SWIG_RubyAddTracking(ptr, obj);
}
return obj; return obj;
} }
@ -121,11 +138,21 @@ SWIG_Ruby_ConvertPtr(VALUE obj, void **ptr, swig_type_info *ty, int flags)
} }
/* Check to see if the input object is giving up ownership /* Check to see if the input object is giving up ownership
of the underlying C struct or C++ object. If so, then of the underlying C struct or C++ object. If so then we
set the free function to nil so that the C struct need to reset the destructor since the Ruby object no
is not freed when the Ruby object goes out of scope.*/ longer owns the underlying C++ object.*/
if (flags & SWIG_POINTER_DISOWN) { if (flags & SWIG_POINTER_DISOWN) {
RDATA(obj)->dfree = 0; if (flags & SWIG_TRACK_OBJECTS) {
/* We are tracking objects. Thus we change the destructor
* to SWIG_RubyRemoveTracking. This allows us to
* remove the mapping from the C++ to Ruby object
* when the Ruby object is garbage collected. If we don't
* do this, then it is possible we will return a reference
* to a Ruby object that no longer exists thereby crashing Ruby. */
RDATA(obj)->dfree = SWIG_RubyRemoveTracking;
} else {
RDATA(obj)->dfree = 0;
}
} }
/* Do type-checking if type info was provided */ /* Do type-checking if type info was provided */