From ndevenish at gmail.com Thu Jun 27 12:32:42 2019 From: ndevenish at gmail.com (Nicholas Devenish) Date: Thu, 27 Jun 2019 17:32:42 +0100 Subject: [C++-sig] Getting the same python instance back in boost::python? Message-ID: I want to get the same python instance back for subsequent calls to the C++ function e.g. I want this to work for the C++ structure below: import ident_ext o = ident_ext.Owner() assert o.get() is o.get() How can I get this behaviour in boost::python? It looked like call policies was the right sort of place to look, but can't get that to behave how I want. I can get this to work in pybind11 but not boost (and unfortunately our project is heavily dependent on boost::python). My working c++ is: #include #include using namespace boost::python; class Something { public: void name(void) { std::cout << this << std::endl; } }; class Owner { Something *_shared = nullptr; public: Something &get() { if (_shared == nullptr) { _shared = new Something(); } return *_shared; } }; BOOST_PYTHON_MODULE(ident_ext) { class_("Something").def("name", &Something::name); class_("Owner").def("get", &Owner::get, return_internal_reference<>()); } From stefanrin at gmail.com Fri Jun 28 13:22:55 2019 From: stefanrin at gmail.com (Stefan Ring) Date: Fri, 28 Jun 2019 19:22:55 +0200 Subject: [C++-sig] Getting the same python instance back in boost::python? In-Reply-To: References: Message-ID: On Fri, Jun 28, 2019 at 2:16 PM Nicholas Devenish wrote: > > I want to get the same python instance back for subsequent calls to > the C++ function e.g. I want this to work for the C++ structure below: > > import ident_ext > o = ident_ext.Owner() > assert o.get() is o.get() > > How can I get this behaviour in boost::python? It looked like call > policies was the right sort of place to look, but can't get that to > behave how I want. I can get this to work in pybind11 but not boost > (and unfortunately our project is heavily dependent on boost::python). > My working c++ is: > > #include > #include > using namespace boost::python; > > class Something { > public: > void name(void) { std::cout << this << std::endl; } > }; > > class Owner { > Something *_shared = nullptr; > > public: > Something &get() { > if (_shared == nullptr) { > _shared = new Something(); > } > return *_shared; > } > }; > > BOOST_PYTHON_MODULE(ident_ext) { > class_("Something").def("name", &Something::name); > class_("Owner").def("get", &Owner::get, return_internal_reference<>()); > } Maybe store a wrapping bp::object in addition to the Something ptr, then always return the same bp::object? That?s how I did it. Ok, you would probably have to create a wrapper for Something just for this. I don?t know how feasible this is.