I've read how to expose normal vectors to python in boost python, but I want to know how to expose and make use of a vector. For instance, I have a vector of shared_ptrs as follows:
std::vector<shared_ptr<StatusEffect> > Effects;
Based on the material for exposing vectors, I should be able to expose this type of class. What I want to know is how can I actually add to it? How do I create instances of shared_ptr<StatusEffect>
since I don't have access to new, and the shared_ptr can point to multiple derived types making adding a static creation method to each class a little tedious.
Does anyone have some pointers or can suggest how to do this? Finding good example for boost::python for what I want to do has been ab开发者_JS百科it tricky
Thanks in advance
struct A {
int index;
static shared_ptr<A> create () { return shared_ptr<A>(new A); }
std::string hello () { return "Just nod if you can hear me!"; }
};
BOOST_PYTHON_MODULE(my_shared_ptr)
{
class_<A, shared_ptr<A> >("A",boost::python::init<>())
.def("create",&A::create )
.staticmethod("create")
.def("hello",&A::hello)
.def_readonly("index",&A::index)
;
boost::python::class_<std::vector<shared_ptr<A>>>("PyVec")
.def(boost::python::vector_indexing_suite<std::vector<shared_ptr< A>>,true >());
}
The argument of ",true" is important!
See Pointers and smart pointers for an example.
You mention that a creation method (constructor) for each class would be a little tedious, but I think that's what you need.
You can partially bind boost::shared_ptr<StatusEffect>
, omitting the construction just fine with Boost.Python (use boost::python::no_init
). To have a similar mechanism with std::shared_ptr<StatusEffect>
you will also need to define a boost::get_pointer<T>()
free function with T = std::shared_ptr<U>
as explained in this other SO thread. Here is a sketch of a workable solution:
#include <boost/python.hpp>
#include <memory>
...
namespace boost {
template<class T> T* get_pointer(std::shared_ptr<T> p) { return p.get(); }
}
BOOST_PYTHON_MODULE(yourmodule) {
using namespace boost::python;
class_<StatusEffect, std::shared_ptr<StatusEffect>, boost::noncopyable>("StatusEffect", no_init);
class_<std::vector<std::shared_ptr<StatusEffect> > >("StatusEffectVector")
.def(boost::python::vector_indexing_suite<std::vector<shared_ptr<StatusEffect>>, true>());
}
精彩评论