On Monday 16 August 2010 14:49:04 Jim Bosch wrote: > On 08/16/2010 02:33 PM, Branan Purvine-Riley wrote: > > I'm working on replacing hand-rolled python bindings with boost.python. > > > > Unfortunately, I've hit a bit of a snag at a particular construct: > > a = someFunction(...) # returns an instance of myClass > > b = myClass(a) > > > > In the current bindings, this creates a new python object that references > > the same internal C++ object. It's effectively no-op, and I have no idea > > why it was written that way in the first place, but I have to maintain > > API compatibility. > > > > That being the case, how do I implement this in boost.python? I > > considered replacing __init__, but it seems if I implement that as a > > standalone function rather than a constructor, boost has already created > > a new C++ instance for me, so that's too late. I'm not really sure what > > else to try. > > You'll want to use the make_constructor function; this takes a C++ > function returning a C++ smart pointer and creates a Python __init__ > overload. > > I *think* this should work (I haven't tested it): > > ---------------------------------------------- > > boost::shared_ptr<MyClass> construct(boost::python::object const & arg) { > return boost::python::extract< boost::shared_ptr<MyClass> >(arg); > } > > BOOST_PYTHON_MODULE(example) { > boost::python::class_<MyClass>("MyClass") > .def("__init__", boost::python::make_constructor(&construct)) > ; > boost::python::register_ptr_to_python< > boost::shared_ptr<MyClass> > > >(); > > } >
That's definitely on the right track. Not quite right because of some of the oddities of what I'm working with here. It's a game engine, and none of the pointers are stored in a smart pointer container of any kind. Unfortunately make_constructor will convert a raw ptr to an std::auto_ptr, which deletes the object somewhere in boost code. What I ended up with is the following: template<typename T> struct dummy_ptr { dummy_ptr(T* p) : ptr(p) {} T* operator->() { return ptr; } T* ptr; typedef T element_type; }; template<typename T> T* get_pointer(const dummy_ptr<T>& dummy) { return dummy.ptr; } template<typename T> dummy_ptr<T> noop_constructor(T* arg) { return dummy_ptr<T>(arg); } BOOST_PYTHON_MODULE(example) { boost::python::class_<MyClass>("MyClass") .def("__init__",boost::python::make_constructor(&noop_constructor<MyClass>)); boost::python::register_ptr_to_python<dummy_ptr<MyClass> >(); } _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig