[C++-sig] set python attribute from C++
jeff.webb at nta-inc.net
Fri Jul 18 19:13:06 CEST 2008
English, Mark wrote:
> However, the scenario I never got passed was this:
> Python code derives a class "PyFoo" from exposed C++ class "Foo".
> Python code creates an instance of "PyFoo" and passes it to C++ code
> which expects a my_smart_ptr<Foo>.
> C++ code stores my_smart_ptr<Foo> in a container for later retrieval.
> Python code deletes its reference to the "PyFoo" instance.
> "PyFoo" object reference count falls to 0 and object is no longer used
> on Python side.
> ...Time passes...
> Python code calls into C++ code to retrieve object stored in C++
> collection of my_smart_ptr<Foo>.
> Internally cached PyObject is returned who's reference count was
> decremented to 0 above.
> Nothing works.
> Alternatively a new PyObject wrapper for the C++ "Foo" instance
> originally contained within the "PyFoo" instance can be returned, but it
> will only appear as a "Foo", and not a "PyFoo".
> Following this route requires some mechanism to say from the C++ side
> that the PyObject needs to remain valid despite no references to it from
> Python. This then leads to issues of how to manage that additional
> lifetime information.
> All in all the holding a PyObject approach looked promising for a while,
> but I suspect it was a mistake.
I did get this approach to work. In my implementation, I had two types of boost::python wrappers that I call persistent and non-persistent. Non-persistent python wrappers disappear when the python reference count goes to zero, which is often what you want when you are just exposing a C++ object. (No sense in keeping around wrappers that you may never use again.) If you are trying to extend a C++ object using python, then this behavior is not what you want. In this case, you need to use a persistent wrapper. Once a persistent python wrapper has been bound to a C++ object, it is not deleted until all references to the C++ object disappear. In other words, a persistent python wrapper is deleted at the same time as the underlying C++ object. Is this the behavior you are looking for? I hope to post some code to this list over the next few days.
More information about the Cplusplus-sig