[C++-sig] weak_ptr to this in C++ classes extended from python
Holger Brandsmeier
brandsmeier at gmx.de
Thu Apr 26 20:49:26 CEST 2012
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 <bcatanzaro at 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.
More information about the Cplusplus-sig
mailing list