[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