[C++-sig] pybindgen: Why does pybindgen want to call constructors for a singleton class?
J. Michael Owen
mikeowen at llnl.gov
Tue Jun 23 02:23:33 CEST 2009
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 <mikeowen at 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 at python.org
> http:// mail.python.org/mailman/listinfo/cplusplus-sig
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20090622/53d1ee7c/attachment.htm>
More information about the Cplusplus-sig
mailing list