[C++-sig] pybindgen: Why does pybindgen want to call constructors for a singleton class?

J. Michael Owen mikeowen at llnl.gov
Mon Jun 22 23:31:13 CEST 2009


I'm looking at wrapping a C++ singleton with pybindgen, and it seems  
that if I expose the method for getting the instance to python the  
generated code wants to call a copy constructor, which seems wrong to  
me.  If for instance I define a class "A" as a singleton:

class A {
public:
   static A* instancePtr() {
     if (A::mInstancePtr == 0) A::mInstancePtr = new A;
     return mInstancePtr;
   }
private:
   A();
   A(const A& rhs);
   A& operator=(const A& rhs);
   static A* mInstancePtr;
};

and I wrap A and its instance method like so:

mod = Module("singleton_example")
mod.add_include('"singleton_example.hh"')
x = mod.add_class("A", is_singleton=True)
x.add_method("instancePtr", retval("A*", caller_owns_return=False), [])

pybindgen generates the following code for the instancePtr method:

PyObject *
_wrap_PyA_instancePtr(PyA *self)
{
     PyObject *py_retval;
     A *retval;
     PyA *py_A;

     retval = self->obj->instancePtr();
     if (!(retval)) {
         Py_INCREF(Py_None);
         return Py_None;
     }
     py_A = PyObject_New(PyA, &PyA_Type);
     py_A->obj = new A(*retval);
     py_retval = Py_BuildValue((char *) "N", py_A);
     return py_retval;
}

As you can see it is trying to construct a new object with a copy of  
the A retval parameter (the line that reads "py_A->obj = new  
A(*retval);".  This is of course forbidden because all of A's  
constructors are private -- as a singleton we don't want anyone  
calling constructors on this object.  Moreover, since I exposed  
"instancePtr" as returning a pointer I did not expect any copies to be  
generated anyway -- I'd like to see the pointer "retval" sent back  
directly (even if this wasn't a singleton).  Am I missing some syntax  
here to prevent pybindgen from trying to make these copies?

Thanks!

Mike.



More information about the Cplusplus-sig mailing list