[C++-sig] Re: problems with weak_ptr to python object
David Abrahams
dave at boost-consulting.com
Tue Dec 14 21:52:14 CET 2004
Arthur Peters wrote:
> Hello,
>
> I am working on a project that uses shared_ptr for more or less
> everything, so weak_ptrs are important. I discovered that the
> shared_ptrs created by boost.python from python objects that use
> shared_ptr as a holder are not shared_ptrs managing the same object as
> the holder, but are shared_ptrs managing a reference to the python
> object. This is fine until you make a weak_ptr to it. Then the weak_ptr
> will become invalid way before the actually object is destroyed.
Interesting.
The way to get at the underlying shared_ptr is to convert the Python
object to a non-const shared_ptr&. So you could do:
template <class T>
weak_ptr<T> get_weak_ptr(shared_ptr<T> const& x)
{
object python_owner(x);
shared_ptr<T>& inner_shared_ptr(
extract<shared_ptr<T>&>(python_owner));
return inner_shared_ptr; // convert to weak_ptr.
};
> See the thread from a year ago called "keeping weak_ptrs upon python
> objects smart_ptrholders"
> (http://mail.python.org/pipermail/c++-sig/2003-November/006337.html).
> There was talk of fixing this problem. Did it go anywhere?
Was a solution proposed? Oh, I see:
----schnipp------
wouldn't it be possible, when converting the arguments provided to a
function, that if :
- a shared_ptr (weak_ptr) argument is the 'target' of a specified implicit
conversion whose source is the type of
the provided value for the argument
- AND the provided value wrapper is held by shared_ptr
- THEN the shared_ptr " conjured up 'from thin air' " is contructed from the
shared_ptr holding the provided value
thus having a valid reference count
I don't if/where/how all this could be done, and if it covers every aspect
of the problem !
-----schnapp------
The problem is that the existing conversion has great value even when
the inner objects are held by shared_ptr. If you're going to pass the
shared_ptr back to Python you should see the same managing object.
Otherwise you can end up with two different Python objects managing the
same C++ base sub-object <shiver>.
> I have had the following thoughts:
>
> The problem is that a shared_ptr directly related (sharing a use_count)
> to the holder
You lost me. Which holder?
> is only passed to C++ if the type requested exactly
> matches the holder (I think).
Example?
> And in other cases, a unrelated (seperate
> use_count) shared_ptr to the same object is passed.
> If a shared_ptr<void> was used in place of the void*s in the converter
> code the shared_ptr-ness could be preserved. It would be silly to use
> shared_ptr<void> when the target type was a plain pointer so maybe it
> would be possible to make a duplicate of a part of the "conversion
> path" that used shared_ptr<void>. This path could be used by
> shared_ptr_from_python to return shared_ptrs that are related to the
> shared_ptr that is the holder.
>
> Does any of that make sense? I'm having trouble explaining my self.
No and yes ;-)
Give some code examples to show what you mean.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
More information about the Cplusplus-sig
mailing list