> Using sip.transfer(), as Phil suggested, keeps the destructor of my > object created by clone() from being destroyed. However, my object > is still not useable as it can't find the Python implemented methods > when it is called from C++ after return of clone. > > Poking around, I found that sipFunctionBase::sipPySelf data member > has gotten reset to zero. Using SIP trace and adding some printing > in the generated sipFunctionBase.cpp file by hand, the trace back > is... > > > FunctionBase * sipFunctionBase::clone() const (this=0x083c9d90) > sipPySelf = 0x419c623c > python.clone > init_FunctionBase sipSelf = 0x419c629c > sipFunctionBase::sipFunctionBase(const FunctionBase&) (this=0x08406528) > sipPySelf = 0 > sipCpp = 0x8406528 > python.copy > dealloc_FunctionBase sipSelf = 0x419c629c > sipIsSimple not > const std::vector<double>& sipFunctionBase::getParameters() > (this=0x08406528) > sipPySelf = 0 > > Note > > - sipFunctionBase::clone() finds the Python member function and calls > it. Looks ok > > - The sipFunctionBase copy constructor gets called followed by Python > __init__ method. Looks ok > > - on return, dealloc_FunctionBase is called with argument of the newly > created instance. It appears that sipPySelf is then set to zero! > > - The very first call to a member function shows indeed that the member > sipPySelf is a null pointer. > > Any ideas, suggestions?
sipPySelf is the pointer to the Python instance object. It is reset to 0 to show that it has been garbage collected. Unfortunately, as you have found, it means the Python virtual reimplementations can no longer work. There is a slight difference between the Python sip.transfer() and the C++ sipTransfer(). The latter creates an extra reference to the Python object to prevent to being garbage collected - the former doesn't because the intent was to completely divorce the Python and C++ objects. You want the behaviour of sipTransfer() rather than sip.transfer(). There are two solutions... I add an optional second argument to sip.transfer() that causes it to behave like sipTransfer() - I will do this anyway in the next few days. You use sipTransfer() - but you must call it before the Python object is garbage collected, ie. you must provide %VirtualCatcherCode for clone(). This is probably what you want to do if you want to make life as easy as possible for your users writing the Python reimplementations. Phil _______________________________________________ PyKDE mailing list [email protected] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
