Possible bug for return_internal_reference with shared_ptr
Hallo, i am using internal reference with shared pointers to handle borrowed references. Here the code: begin cpp-------------------- #include <boost/shared_ptr.hpp> #include <boost/python.hpp> using namespace boost; using namespace python; class B { public: B() : _a(0) {} void set(const int & a) { _a = a; } const int & get() const { return _a; } private: int _a; }; typedef shared_ptr<B> ptr_type; class A { public: A() : _a(new B()) {} void set(const ptr_type & a) { _a = a; } const ptr_type & get1() const { return _a; } const ptr_type & get2() const { return _a; } private: ptr_type _a; }; BOOST_PYTHON_MODULE(ptr_test) { class_<A, shared_ptr<A> >("A") .def("set", &A::set) .def("get1", &A::get1, return_value_policy<copy_const_reference>()) .def("get2", &A::get2, return_internal_reference<>()) ; class_<B, shared_ptr<B> >("B") .def("set", &B::set) .def("get", &B::get, return_value_policy<copy_const_reference>()) ; } end cpp --------------------- begin python --------- from ptr_test import * a = A() b1 = a.get1() print b1.get() b2 = a.get2() print b2.get() end python -------------------- If I execute the python script I get the following error message: TypeError: No Python class registered for C++ class boost::shared_ptr<B> begin out -------------------- 0 Traceback (most recent call last): File "test.py", line 8, in ? b2 = a.get2() TypeError: No Python class registered for C++ class boost::shared_ptr<B> end out ----------------------- So return_value_policy<copy_const_reference> is working and return_internal_reference<> not! Any ideas why boost/python can not handle this? I think to handle internal references is importend for containers and iterators.
"Dr. Michael Knecht" <michael.knecht@nanotechsoftware.de> writes:
Hallo,
i am using internal reference with shared pointers to handle borrowed references.
<shiver> I *really* think you don't want to do that.
Here the code:
begin cpp-------------------- #include <boost/shared_ptr.hpp> #include <boost/python.hpp>
using namespace boost; using namespace python;
class B { public: B() : _a(0) {} void set(const int & a) { _a = a; } const int & get() const { return _a; } private: int _a; };
typedef shared_ptr<B> ptr_type;
class A { public: A() : _a(new B()) {} void set(const ptr_type & a) { _a = a; } const ptr_type & get1() const { return _a; } const ptr_type & get2() const { return _a; } private: ptr_type _a; };
BOOST_PYTHON_MODULE(ptr_test) { class_<A, shared_ptr<A> >("A") .def("set", &A::set) .def("get1", &A::get1, return_value_policy<copy_const_reference>()) .def("get2", &A::get2, return_internal_reference<>()) ; class_<B, shared_ptr<B> >("B") .def("set", &B::set) .def("get", &B::get, return_value_policy<copy_const_reference>()) ; } end cpp ---------------------
begin python --------- from ptr_test import *
a = A()
b1 = a.get1() print b1.get()
b2 = a.get2() print b2.get() end python --------------------
If I execute the python script I get the following error message:
TypeError: No Python class registered for C++ class boost::shared_ptr<B>
begin out -------------------- 0 Traceback (most recent call last): File "test.py", line 8, in ? b2 = a.get2() TypeError: No Python class registered for C++ class boost::shared_ptr<B> end out -----------------------
So return_value_policy<copy_const_reference> is working
As it should.
and return_internal_reference<> not!
Any ideas why boost/python can not handle this? I think to handle internal references is importend for containers and iterators.
Because return_internal_reference doesn't do what you think. It builds an instance of the Python class corresponding to the type referenced, and holding a pointer to the thing referenced (a shared_ptr in this case) and maintaining the lifetime of the first argument in order to keep the thing pointed to alive. You didn't (and shouldn't) register a class corresponding to shared_ptr<B>; you just used shared_ptr<B> to hold the value of a class corresponding to B. It might be nice if Boost.Python would let you get away with no return_value_policy in these cases, but I have some doubts about allowing return_internal_reference for shared_ptr<T>. It would be wasteful at best because it isn't really important to keep the first argument to the wrapped function alive at all; the shared_ptr is enough to keep the B object it references alive. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (2)
-
David Abrahams -
Dr. Michael Knecht