David Abrahams wrote: > on Mon Nov 10 2008, Paul Melis <paul-AT-pecm.nl> wrote: > > >> The FAQ entry on this doesn't really help, so perhaps I'm not using the >> return policy >> correctly or missing something else. The full test code (which is actually >> quite >> small) is attached. >> > > Please reduce it to its absolute minimum. Remove every single thing you > don't need in order to produce the result. If the problem isn't > glaringly obvious to you then, I will help. > Well, I tried reducing in several different ways. The bottom line is that I can't seem to produce this without using the wrapper class (or perhaps I missed the right combination of return policies).
Simplest test case (see below for the rest of the files): #!/usr/bin/env python from boost import * class MyCallback(Callback): def __init__(self): Callback.__init__(self) def __call__(self): return Value() cb = MyCallback() r = go(cb) Storing a reference to the Value instance returned in __call__ keeps the instance alive, so the dangling pointer is caused by the Value instance that is returned getting destructed. But this only happens when the instance is passed through go() as its return value. When calling cb directly the Value is not destructed (as I would expect). What I don't understand is why it is destructed when it *is* passed through go(), shouldn't the manage_new_object policy keep it alive? Regards, Paul // classes.h #ifndef CLASSES_H #define CLASSES_H #include <stdlib.h> class Value { public: Value() { printf("Value::Value()\n"); } Value(const Value& v) { printf("Value::Value(const Value& v)\n"); } ~Value() { printf("Value::~Value()\n"); } }; class Callback { public: Callback() {} Callback(const Callback& cb) {} virtual ~Callback() {} // Returns new Value instance virtual Value* operator()() { return new Value(); } }; Value *go(Callback *cb) { return (*cb)(); }; #endif // boost.cpp // g++ -shared -fPIC -O3 -o boost.so -I/usr/include/python2.5 boost.cpp -lboost_python -lpython2.5 #include <boost/python.hpp> #include "classes.h" namespace bp = boost::python; struct CallbackWrap : Callback, bp::wrapper<Callback> { virtual Value *operator()() { printf("CallbackWrap::operator()\n"); if (bp::override call = this->get_override("__call__")) { printf("Have override for __call__, calling it\n"); return call(); } return Callback::operator()(); } Value *default_call() { printf("CallbackWrap::default_call()\n"); return this->Callback::operator()(); } }; BOOST_PYTHON_MODULE(boost) { bp::class_< Value >("Value"); bp::class_< CallbackWrap, boost::noncopyable >("Callback") .def("__call__", &Callback::operator(), &CallbackWrap::default_call, bp::return_value_policy<bp::manage_new_object>()); bp::def("go", &go, bp::return_value_policy<bp::manage_new_object>()); } _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig