[C++-sig] Re: Getting Python Object for C++ object
David Abrahams
dave at boost-consulting.com
Thu Aug 14 02:51:35 CEST 2003
Anxious to clear this from my "unread" pile, I'm going to try to
help...
abeyer at uni-osnabrueck.de writes:
> It is already a classical problem: I would like to find the python object
> for a given C++ object from within the C++ object. However, there is no
> way I gonna wrap the classes as shown in the corresponding Howto
> example.
I assume that you mean creating a wrapper subclass is impossible for
you. Understandable.
> Thus, I will have to use shared_ptr instead.
Since you seem to be willing to change interfaces, you can modify the
class itself to take an initial PyObject* argument and specialize
boost::python::has_back_reference:
namespace boost { namespace python {
template <>
struct has_back_reference<MyClass>
: mpl::true_
{};
}}
But this is hardly a more attractive solution.
> Eventually I would like to call peer-objects with 'self' as an argument
> from within C++ as well as from python. (BTW the latter is quite simple.)
> My first attempt was the following:
>
> class A : public enable_shared_from_this<A> {
> public:
> virtual python::object get_self() {
> shared_ptr<A> self = shared_from_this();
> assert(self != 0);
> return python::object(self.get());
^^^^^^^^^^
This will trip you up. Boost.Python can't convert a raw pointer into
an existing Python object; when you explicitly convert a pointer to
Python it creates a new Python object and copies the pointee. You want
return python::object(self);
instead.
> }
>
> virtual ~A() {};
> };
>
> Certainly this only works after a shared pointer has
> actually been created, e.g. by adding 'a' to another object
> which only accepts shared_ptr<A>. Like:
>
> typedef shared_ptr<A> A_ptr;
> class C {
> public:
> void set(A_ptr a) {this->a = a;}
> A_ptr get() { return this->a; };
> private:
> A_ptr a;
> };
>
> This will create a shared_ptr for an instance of 'A' if it gets
> added to 'C' with set().
Yes, but it won't make the shared_from_this() call succeed unless
you've assigned that shared_ptr into a->_internal_weak_this.
[Peter, I notice that enable_shared_from_this.hpp is mentioned in the
docs and enable_shared_from_this<> is mentioned in the sp_techniques
doc, but there's no mention of this crucial fact]
> After that, shared_from_this() actually returns a valid
> shared_ptr. However, that pointer apparently points to another
> (new?) shared_ptr, because the python::object returned is a new
> one. (Who can explain why shared_from_this() doesn't return the
> shared_ptr created by boost:python?)
I hope I already have. I didn't read the stuff that follows; please
let me know if I still need to.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list