如何导出std::vector
我正在使用boost.python库写一个应用程序。我想把一个返回std::vector
的函数传递给Python。不过我遇到了一些小问题:
inline std::vector<std::string> getConfigListValue(const std::string &key)
{
return configManager().getListValue(key);
}
BOOST_PYTHON_MODULE(MyModule)
{
bp::def("getListValue", getListValue);
}
当我从Python调用这个函数时,我得到了:
TypeError: No to_python (by-value) converter found for C++ type: std::vector<std::string, std::allocator<std::string> >
我漏掉了什么呢?
3 个回答
1
我使用以下工具函数来在stl容器之间进行转换。下面这个简单的求和函数展示了这些工具函数是怎么用的。希望你能用得上。
#include <vector>
#include <boost/python.hpp>
#include <boost/python/object.hpp>
#include <boost/python/stl_iterator.hpp>
namespace bpy = boost::python;
namespace fm {
template <typename Container>
bpy::list stl2py(const Container& vec) {
typedef typename Container::value_type T;
bpy::list lst;
std::for_each(vec.begin(), vec.end(), [&](const T& t) { lst.append(t); });
return lst;
}
template <typename Container>
void py2stl(const bpy::list& lst, Container& vec) {
typedef typename Container::value_type T;
bpy::stl_input_iterator<T> beg(lst), end;
std::for_each(beg, end, [&](const T& t) { vec.push_back(t); });
}
bpy::list sum(const bpy::list& lhs, const bpy::list& rhs) {
std::vector<double> lhsv;
py2stl(lhs, lhsv);
std::vector<double> rhsv;
py2stl(rhs, rhsv);
std::vector<double> result(lhsv.size(), 0.0);
for (int i = 0; i < lhsv.size(); ++i) {
result[i] = lhsv[i] + rhsv[i];
}
return stl2py(result);
}
} // namespace fm
BOOST_PYTHON_MODULE(entry)
{
// intended to be fast math's fast sum :)
bpy::def("sum", &fm::sum);
}
3
这个问题有点老了,但我发现如果你明确要求返回一个值,比如这样:
namespace bp = boost::python
BOOST_PYTHON_MODULE(MyModule)
{
bp::def("getListValue", getListValue,
bp::return_value_policy<bp::return_by_value>());
}
而不是这样:
BOOST_PYTHON_MODULE(MyModule)
{
bp::def("getListValue", getListValue);
}
Python会自动帮你转换(我写这个回答时用的是Python 2.7),所以你不需要自己去声明或定义转换器。
@Tryskele
12
你应该写一个这样的转换器:
template<class T>
struct VecToList
{
static PyObject* convert(const std::vector<T>& vec)
{
boost::python::list* l = new boost::python::list();
for(size_t i = 0; i < vec.size(); i++) {
l->append(vec[i]);
}
return l->ptr();
}
};
然后在你的模块中注册它:
BOOST_PYTHON_MODULE(MyModule)
{
boost::python::to_python_converter<std::vector<std::string, std::allocator<std::string> >, VecToList<std::string> >();
boost::python::def("getListValue", getListValue);
}