I think the problem is that aa is no longer an ExtendedA object, because when you call ptr() it returns a pointer to the base C++ A class, not the derived class.
I think at this point it's probably best to reconsider the problem and come up with a simpler solution. Why do you want to expose the ptr method to Python anyway? - bryan On Thu, Apr 26, 2012 at 11:49 AM, Holger Brandsmeier <brandsme...@gmx.de> wrote: > Bryan, > > my problems happen as soon as I need to use wrappers. I really need > the class that I extend in python to implement some pure virtual > function in the C++ class. I extended your code and refined what is > going wrong. I tried several Variants with different errors, I used > #defines to show you all 4 versions, next to each Variant I put a C++ > comment of what is going wrong. > > So here it is: > > ------------ foo.cpp ------------ > #include <boost/python.hpp> > #include <boost/shared_ptr.hpp> > #include <boost/enable_shared_from_this.hpp> > #include <iostream> > > using namespace boost::python; > > class A > : public boost::enable_shared_from_this<A> { > static int counter; > public: > int id; > A() { > id = counter++; > std::cout << "Constructing A[" << id << "]" << std::endl; > } > ~A() { > std::cout << "Destructing A[" << id << "]" << std::endl; > } > boost::shared_ptr<A> ptr() { > return shared_from_this(); > } > #define VARIANT0 > #ifdef VARIANT0 > // this variant works nicely with VARIANT1 below (compiles and > // no error for `aa = a.ptr()`), but it produces wrong results, > // i.e. `77` is returned for `aa.foo()` although it should have > // been `33`. > virtual int foo() { > return 77; > } > #else > virtual int foo() = 0; > #endif > }; > > struct AWrapper : public A, public boost::python::wrapper<A> { > virtual int foo() { > if( override f = this->get_override("foo") ) { > return f(); > } else { > return 42; > } > } > }; > > int A::counter = 0; > > using namespace boost::python; > > > BOOST_PYTHON_MODULE(foo) { > #define VARIANT1 > //#define VARIANT2 > //#define VARIANT3 > > #ifdef VARIANT1 > // The following line doesn't compites it gives the error: > // error: cannot allocate an object of abstract type ‘A’ > class_<AWrapper, boost::shared_ptr<A>, boost::noncopyable >("A", init<>()) > #endif > #ifdef VARIANT2 > // the following compiles, but produces an error in python, when executing > // aa = a.ptr(); > // RuntimeError: tr1::bad_weak_ptr > class_<AWrapper, boost::noncopyable >("A", init<>()) > #endif > #ifdef VARIANT3 > // the following compiles, but produces an error in python, when executing > // aa = a.ptr(); > // TypeError: No to_python (by-value) converter found for C++ type: > boost::shared_ptr<A> > class_<AWrapper, boost::shared_ptr<AWrapper>, boost::noncopyable >>("A", init<>()) > #endif > .def("ptr", &A::ptr) > .def("foo", &A::foo) > ; > } > ----------------------------------- > > ------------ foo.py ------------ > import foo > > class ExtendedA(foo.A): > def foo(self): > return 33; > > a0 = foo.A() > a = ExtendedA() > aa = a.ptr(); > print a.foo() > del a > print aa.foo() > ----------------------------------- > > Do you have any suggestion how to get this working? > -Holger > > On Thu, Apr 26, 2012 at 18:43, Bryan Catanzaro <bcatanz...@acm.org> wrote: >> Holger Brandsmeier <brandsmeier <at> gmx.de> writes: >> >>> >>> Dear list, >>> >>> how is it possible to have a class in C++ that can be extended from >>> python and that stores a weak_ptr to itself? >> >> >> Have you tried using boost::enable_shared_from_this? The following example >> code >> seems to do what you want. > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig@python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig