voodoogiant
voodoogiant

Reputation: 2148

Smart pointers with PythonQt

My app uses QSharedPointers throughout the C++ API, where instead of returning an object, it usually returns a smart pointer to it and every class has an accompanying typedef for convenience.

class SomeClass
{
 SomeClassP getInstance() { return SomeClassP(new SomeClass()); }
}
typedef QSharedPointer<SomeClass> SomeClassP;

This has worked well, but I'm wondering how/if my design needs to be altered to handle PythonQt integration. For example, in a PythonQtWrapper what should I return from pointers? If I'm dealing with pointers in python, how can I call other functions that take a smart pointer and not a normal pointer? Do I need to expose the smart pointer to PythonQt? It seems that in boost::python a lot of the smart pointer stuff was taken care of automatically. What needs to be done in my case? Should I add additional functions in C++ that accept non-smart-pointers that simply wrap the pointer in a smart pointer and send it on to the smart-pointer-accepting function? It seems the python API has some fairly complex rules regarding pointer ownership.

class PythonQtWrapper_SomeClass : public QObject
{
   Q_OBJECT
public slots:
   SomeClass* new_SomeClass() { return new SomeClass(); }
   void delete_Mesh(SomeClass* obj) { delete obj; }
   SomeClass* static_SomeClass_build(int foo) {
       SomeClassP ack = SomeFactory::build(foo);
       return ?
   }
};

Upvotes: 0

Views: 447

Answers (1)

Toni Alatalo
Toni Alatalo

Reputation: 11

We are having this exact same problem, and don't have a great solution yet.

Earlier resorted to adding variants of funcs that returned raw pointers instead. Then we got rid of those, and am now decorating smart pointers in PythonQt so that py code can call .get() on them to get the raw pointer. This is how I just made a first experimental switch to that style: (from https://github.com/realXtend/naali/commit/e72cb827c7fcbaee27b8258e616ee7bd2835fbd7 )

//Ptr conversions, not automatic but with an explicit call
int scenePtr_id = qRegisterMetaType<ScenePtr>("ScenePtr");
QObject* TundraDecorator::get(ScenePtr* self)
{
    return self->get();
}

Am not sure if that is safe even but seems to work. Am very interested if there are better solutions.

Upvotes: 1

Related Questions