On Fri, Apr 27, 2012 at 08:22, Bryan Catanzaro <bcatanz...@acm.org> wrote: > 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 you got something confused. A boost::shared_pointer<A> can very well be any pointer to any derived class, no copy should be created. I can still call virtual functions from `A` and should get the result from the implementation of `ExtendedA`. > 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? I don't plan to call `ptr()` from python, but I will call the same function from C++ and and at some point the result that C++ produced can find its way back to python. I did find a different solution to this problem: On Mon, Apr 23, 2012 at 20:48, Holger Brandsmeier <brandsme...@gmx.de> wrote: > In the meantime I figured out a different way of doing the shared > pointer from this in python. Namely, to just make getThisRCP() a > virtual function, add it to the Wrapper and to implement it in the > python by implementing it as but I still expect the above mentioned approch with `boost::enable_shared_from_this` _should_ have worked with boost python. I seem to run into an issue that even Dave can not explain (well lets wait for his reply). Moreover note that in boost::python usually if C++ returns a `shared_ptr<A>` which has previously been created as an instance of `ExtendedA` inside python, than this class is available as `ExtendedA`. There is some magic with custom deleters that usually makes you able to treat that class as instance of `ExtendedA`. This magic will also stop working when you use `boost::enable_shared_from_this`. With that aspect I can live, though. -Holger > 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 _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig