使用 Boost.python 将 Python 列表传递给 C++ 向量

10
我如何将我的Python对象类型为ClassName的列表传递给接受vector<ClassName>的C++函数?
最好的方法类似于这样:示例。不幸的是,代码会崩溃,我似乎无法弄清原因。这是我使用的内容:
template<typename T>
void python_to_vector(boost::python::object o, vector<T>* v) {
    try {
      object iter_obj = object(handle<>(PyObject_GetIter(o.ptr())));
      return;
      for (;;) {
          object obj = extract<object>(iter_obj.attr("next")());
          // Should launch an exception if it cannot extract T
          v->emplace_back(extract<T>(obj));
      }
    } catch(error_already_set) {
        PyErr_Clear();
        // If there is an exception (no iterator, extract failed or end of the
        // list reached), clear it and exit the function
        return;
    }
}
2个回答

14
假设您有一个接受 std::vector<Foo> 参数的函数。
void bar (std::vector<Foo> arg)

最简单的处理方式是将vector暴露给Python。

BOOST_PYTHON_MODULE(awesome_module)
{
    class_<Foo>("Foo")
        //methods and attrs here
    ;

    class_<std::vector<Foo> >("VectorOfFoo")
        .def(vector_indexing_suite<std::vector<foo> >() )
    ;

    .def("bar", &bar)
}

现在在Python中,我们可以将Foo放入vector中,并将该向量传递给bar

from awesome_module import *
foo_vector = VectorOfFoo()
foo_vector.extend(Foo(arg) for arg in arglist)
bar(foo_vector)

非常感谢。是否有一种方法可以实现从列表到向量的自动转换? - Neil G
很遗憾,不行。但是,你可以在Python端编写一个函数,将列表转换为向量,并将其传递给bar函数。这将有助于隐藏C++的丑陋。 - Matthew Scouten

3

我找到了一个迭代器,解决了我的问题:

#include <boost/python/stl_iterator.hpp>
template<typename T>
void python_to_vector(boost::python::object o, vector<T>* v) {
    stl_input_iterator<T> begin(o);
    stl_input_iterator<T> end;
    v->clear();
    v->insert(v->end(), begin, end);
}

在Python端完成这项工作会更容易。只需使用vector_indexing_suite包装向量,并在将其交给C++之前在Python中添加所需内容即可。 - Matthew Scouten
@Matthew:你介意加个回答吗?我不知道你的意思。 - Neil G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接