[C++-sig] ownership of C++ object extended in Python

Roman Yakovenko roman.yakovenko at gmail.com
Mon Mar 19 21:01:45 CET 2007


On 3/19/07, Mark Williams <mark at image-engine.com> wrote:
>
> In the Python FAQ Wiki at http://wiki.python.org/moin/boost.python/HowTo
> I see a heading titled "ownership of C++ object extended in Python"
> which discusses how to keep a PyObject* alive while the object it
> represents still exists in C++. It suggests writing a wrapper as follows:
>
> class MyClassWrap : public MyClass
> {
>    MyClassWrap( PyObject* self_) : self(self_) { PyINCREF(self); }
>    MyClassWrap( PyObject* self_, const MyClass& copy ) : MyClass(copy),
> self(self_) { PyINCREF(self); }
>    ~MyClassWrap() { PyDECREF(self); }
>    ...
>    PyObject *self;
> };
>
>
> I'm guessing (probably incorrectly) that this was written before the
> introduction of boost::python::wrapper<>. What I'd like to do is
> something like..
>
> class MyClassWrap : public MyClass, wrapper<MyClass>
> {
>         MyClassWrap()
>         {
>                  Py_INCREF( detail::wrapper_base_::get_owner(*this) )
>         }
>
>         ~MyClassWrap()
>         {
>                 Py_DECREF( detail::wrapper_base_::get_owner(*this) )
>         }
>
>         /* ... wrapped methods here ... */
> }
>
> class_<
>    MyClass,
>    boost::intrusive_ptr<MyClass>,
>    boost::noncopyable>("MyClass");

You wanted to write MyClassWrap, right?

> .. but of course get_owner returns 0 from within MyClassWrap()
>
> What is the correct way of incrementing/decrementing the reference count
> for the underlying PyObject* when using wrapper<>, please?

This is because Boost.Python first creates instance of class
MyClassWrap and only than it initializes "owner" - reference to "self"
object.

The only way to handle it right is inject "initialize on first use"
code in every virtual
function call. I even added this option to Py++.

Take a look on transfer_ownership_tester.py (
http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/
)
You will find header file in "data" directory.
I attached the generated code.

-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: transfer_ownership.cpp
Type: text/x-c++src
Size: 4568 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20070319/6fd1f8ff/attachment.cpp>


More information about the Cplusplus-sig mailing list