2011-03-15 50 views
7

我正在用boost.python庫編寫應用程序。我想將函數傳遞給Python返回std::vector。我有一個小麻煩:如何導出std :: vector

inline std::vector<std::string> getConfigListValue(const std::string &key) 
{ 
    return configManager().getListValue(key); 
} 

BOOST_PYTHON_MODULE(MyModule) 
{ 
    bp::def("getListValue", getListValue); 
} 

當我調用該函數從蟒蛇,我得到:

TypeError: No to_python (by-value) converter found for C++ type: std::vector<std::string, std::allocator<std::string> > 

有什麼我錯過了?

回答

8

你應該寫這樣的轉換器:

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); 
} 
+0

非常感謝,它的工作原理。 – Ockonal 2011-03-15 16:27:41

+0

順便說一句,你爲什麼在'std :: allocator'之前寫'class'? – Ockonal 2011-03-15 16:30:09

+1

....我真的不知道!我刪除它,它仍然有效 – 2011-03-15 16:33:58

0

這是一個有點老問題,但我發現,如果你明確需要由價值迴歸,就像這樣:

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

我使用下面的實用函數來從/到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); 
}