Как экспортировать std :: vector - PullRequest
9 голосов
/ 15 марта 2011

Я пишу приложение с библиотекой boost.python.Я хочу передать функцию в Python, который возвращает std::vector.У меня есть небольшие проблемы:

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 ]

10 голосов
/ 15 марта 2011

Вы должны написать конвертер так:

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);
}
1 голос
/ 23 января 2015

Это немного старый вопрос, но я обнаружил, что если вам явно требуется возвращать по значению, например, так:

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

0 голосов
/ 25 февраля 2018

Я использую следующие служебные функции для преобразования из / в 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...