in reply to Re^5: perl embedded in C++: how to undefine perl objects that are blessed references to C++ objects when the C++ object destructs
in thread perl embedded in C++: how to undefine perl objects that are blessed references to C++ objects when the C++ object destructs

My perly C++ objects all inherit from PClass.

Interesting bit of the PClass constructor:

/* The SV holding the pointer to the actual object is hidden away +in the interpreter. Users aren't supposed to be able to get at it. * +/ SV* theObjRef = newSV(0); sv_setref_pv( theObjRef, 0, (void*)this ); /* Now we bless a reference to theObj. * PClasses are not hashrefs like normal perl classes. They are a + blessed * reference to a pointer to a C++ obj. Phew! * Stuff in the typemap deals with dereferencing the blessed refer +ence. */ SV* theRef = newRV_noinc(theObjRef); //Make a reference to the ref +erence. noinc: when the last reference is gone, theObj should disapp +ear. sv_bless( theRef, gv_stashpv(name.c_str(), GV_ADD) ); sv_setsv(svrep.sv, theRef); # svrep is member var. Its type is j +ust a little convenience wrapper around SV* with some RAII stuff. if (name != "PClass") { // Tell the class on the perl side that it inherits from PClas +s. std::string class_isa = name + std::string("::ISA"); av_push( get_av(class_isa.c_str(), 1), newSVpv("PClass", 0) ); // If the user provided an XS method to pull XS methods into t +he perl interpreter, call that. if (booterSub) _bootModule(name, booterSub); // If a "name".pm is in the @INC path, try to load it up. // eval_pv(std::string(std::string("eval qq{ use ") + n +ame + "}").c_str(), true); }

Interesting bit of the PClass destructor. After this is run all copies of the PClass on the perl side now point to undef and any member functions will will bitch about it:

sv_setsv(SvRV(svrep.sv), Nullsv);

PClass dereference (${}) is overloaded to only return a reference to self. No real dereferencing possible from the perl side:

RETVAL = newRV_inc(lobj);

PClass bool context is overloaded to test for undef in the referenced SV:

RETVAL = SvOK(SvRV(lobj));

The typemap:

TYPEMAP PClass* CPP_OBJECT OUTPUT CPP_OBJECT SV* theObjRef = newSV(0); sv_setref_pv( theObjRef, 0, (void*)$var ); SV* rv = newRV_noinc(theObjRef); sv_bless( rv, gv_stashpv(CLASS, GV_ADD) ); sv_setsv($arg, rv); INPUT CPP_OBJECT $var = ($type) SvIV(SvRV((SV*)SvRV($arg)));

Then pretty standard C++ style XS works fine elsewhere:

bool PClass::some_func() CODE: RETVAL = THIS->someCppFunc(); OUTPUT: RETVAL

To give a C++ object a perl interface you inherit from PClass, define the XS, and add it to the typemap as a CPP_OBJECT. Then you can pass the objects to perl code that can interact with it.

  • Comment on Re^6: perl embedded in C++: how to undefine perl objects that are blessed references to C++ objects when the C++ object destructs
  • Select or Download Code