Ah, I see! That does the trick! Thank you very much. I was clearly confused about what "caller_owns_return" meant -- I had it backwards.

Mike.

On Jun 22, 2009, at 5:11 PM, Gustavo Carneiro wrote:



2009/6/22 J. Michael Owen <mikeo...@llnl.gov>
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?

It tries to copy because you say caller_owns_return=False, pybindgen needs to copy the object so that the wrapper can own the object. What you can do here is use caller_owns_return=True instead of False. It's OK in this case; because of the is_singleton option, the C++ wrapped object will never be freed when the wrapper is destroyed.

--
Gustavo J. A. M. Carneiro
INESC Porto, Telecommunications and Multimedia Unit
"The universe is always one step beyond logic." -- Frank Herbert
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http:// mail.python.org/mailman/listinfo/cplusplus-sig

_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to