使用boost.python包装结构列表 我有一个C++函数,返回结构列表。在结构内部,有更多的结构列表 struct CameraInfo { CamName name; std::list<CamImageFormat> lImgFormats; std::list<CamControls> lCamControls; }; std::list<CameraInfo> getCameraInfo() { std::list<CameraInfo> lCamerasInfo; // fill lCamerasInfo return lCamerasInfo; }

使用boost.python包装结构列表 我有一个C++函数,返回结构列表。在结构内部,有更多的结构列表 struct CameraInfo { CamName name; std::list<CamImageFormat> lImgFormats; std::list<CamControls> lCamControls; }; std::list<CameraInfo> getCameraInfo() { std::list<CameraInfo> lCamerasInfo; // fill lCamerasInfo return lCamerasInfo; },c++,python,list,word-wrap,boost-python,C++,Python,List,Word Wrap,Boost Python,这可能吗??我应该改用add_属性吗?我不认为我可以为每个结构创建一个类。这个设计在我只使用C++的时候是有意义的,但是现在我必须把它包起来,我变得越来越困惑。 任何关于用boost.python以通用方式包装std::list的建议都会被广泛接受 编辑: 我将在此处添加我发现有用的链接: 是否必须是std::list?如果改用std::vector,则可以使用boost::python::vector\u index\u suite来包装列表。有关详细信息,请参阅 如果必须使用std::lis

这可能吗??我应该改用add_属性吗?我不认为我可以为每个结构创建一个类。这个设计在我只使用C++的时候是有意义的,但是现在我必须把它包起来,我变得越来越困惑。 任何关于用boost.python以通用方式包装std::list的建议都会被广泛接受

编辑: 我将在此处添加我发现有用的链接:
是否必须是
std::list
?如果改用
std::vector
,则可以使用
boost::python::vector\u index\u suite
来包装列表。有关详细信息,请参阅

如果必须使用
std::list
,则需要创建一个帮助器类,用python的
list
方法包装
std::list
功能。这可能相当复杂,但可行

标准项目。水电站:

#include <list>
#include <algorithm>
#include <boost/python.hpp>

template<class T>
struct listwrap
{
    typedef typename T::value_type value_type;
    typedef typename T::iterator iter_type;

    static void add(T & x, value_type const& v)
    {
        x.push_back(v);
    }

    static bool in(T const& x, value_type const& v)
    {
        return std::find(x.begin(), x.end(), v) != x.end();
    }

    static int index(T const& x, value_type const& v)
    {
        int i = 0;
        for(T::const_iterator it=x.begin(); it!=x.end(); ++it,++i)
            if( *it == v ) return i;

        PyErr_SetString(PyExc_ValueError, "Value not in the list");
        throw boost::python::error_already_set();
    }

    static void del(T& x, int i)
    {
        if( i<0 ) 
            i += x.size();

        iter_type it = x.begin();
        for (int pos = 0; pos < i; ++pos)
            ++it;

        if( i >= 0 && i < (int)x.size() ) {
            x.erase(it);
        } else {
            PyErr_SetString(PyExc_IndexError, "Index out of range");
            boost::python::throw_error_already_set();
        }
    }

    static value_type& get(T& x, int i)
    {
        if( i < 0 ) 
            i += x.size();

        if( i >= 0 && i < (int)x.size() ) {
            iter_type it = x.begin(); 
            for(int pos = 0; pos < i; ++pos)
                ++it;
            return *it;                             
        } else {
            PyErr_SetString(PyExc_IndexError, "Index out of range");
            throw boost::python::error_already_set();
        }
    }

    static void set(T& x, int i, value_type const& v)
    {
        if( i < 0 ) 
            i += x.size();

        if( i >= 0 && i < (int)x.size() ) {
            iter_type it = x.begin(); 
            for(int pos = 0; pos < i; ++pos)
                ++it;
            *it = v;
        } else {
            PyErr_SetString(PyExc_IndexError, "Index out of range");
            boost::python::throw_error_already_set();
        }
    }
};


template<class T>
void export_STLList(const char* typeName)
{
    using namespace boost::python;

    class_<std::list<T> >(typeName)
        .def("__len__", &std::list<T>::size)
        .def("clear", &std::list<T>::clear)
        .def("append", &listwrap<T>::add,
            with_custodian_and_ward<1,2>()) // to let container keep value
        .def("__getitem__", &listwrap<T>::get,
            return_value_policy<copy_non_const_reference>())
        .def("__setitem__", &listwrap<T>::set,
            with_custodian_and_ward<1,2>()) // to let container keep value
        .def("__delitem__", &listwrap<T>::del)
        .def("__contains__", &listwrap<T>::in)
        .def("__iter__", iterator<std::list<T> >())
        .def("index", &listwrap<T>::index);
}
typedef std::list<int> intlist;
export_STLList<int>("intlist");
#包括
#包括
#包括
模板
结构listwrap
{
typedef typename T::value_type value_type;
typedef typename T::迭代器iter_type;
静态无效添加(T&x、值类型常量和v)
{
x、 推回(v);
}
静态布尔输入(T常量和x,值类型常量和v)
{
返回std::find(x.begin(),x.end(),v)!=x.end();
}
静态整数索引(T常量和x,值类型常量和v)
{
int i=0;
对于(T::const_迭代器it=x.begin();it!=x.end();++it,++i)
如果(*it==v)返回i;
PyErr_SetString(PyExc_ValueError,“值不在列表中”);
抛出boost::python::error_ready_set();
}
静态无效数据集(T&x,int i)
{
如果(i=0&&i<(int)x.size()){
x、 抹去(它);
}否则{
PyErr_SetString(PyExc_索引器,“索引超出范围”);
boost::python::throw_error_ready_set();
}
}
静态值类型和获取(T&x,int i)
{
if(i<0)
i+=x.尺寸();
如果(i>=0&&i<(int)x.size()){
iter_type it=x.begin();
用于(int pos=0;pos=0&&i<(int)x.size()){
iter_type it=x.begin();
用于(int pos=0;pos
用法:

#include <list>
#include <algorithm>
#include <boost/python.hpp>

template<class T>
struct listwrap
{
    typedef typename T::value_type value_type;
    typedef typename T::iterator iter_type;

    static void add(T & x, value_type const& v)
    {
        x.push_back(v);
    }

    static bool in(T const& x, value_type const& v)
    {
        return std::find(x.begin(), x.end(), v) != x.end();
    }

    static int index(T const& x, value_type const& v)
    {
        int i = 0;
        for(T::const_iterator it=x.begin(); it!=x.end(); ++it,++i)
            if( *it == v ) return i;

        PyErr_SetString(PyExc_ValueError, "Value not in the list");
        throw boost::python::error_already_set();
    }

    static void del(T& x, int i)
    {
        if( i<0 ) 
            i += x.size();

        iter_type it = x.begin();
        for (int pos = 0; pos < i; ++pos)
            ++it;

        if( i >= 0 && i < (int)x.size() ) {
            x.erase(it);
        } else {
            PyErr_SetString(PyExc_IndexError, "Index out of range");
            boost::python::throw_error_already_set();
        }
    }

    static value_type& get(T& x, int i)
    {
        if( i < 0 ) 
            i += x.size();

        if( i >= 0 && i < (int)x.size() ) {
            iter_type it = x.begin(); 
            for(int pos = 0; pos < i; ++pos)
                ++it;
            return *it;                             
        } else {
            PyErr_SetString(PyExc_IndexError, "Index out of range");
            throw boost::python::error_already_set();
        }
    }

    static void set(T& x, int i, value_type const& v)
    {
        if( i < 0 ) 
            i += x.size();

        if( i >= 0 && i < (int)x.size() ) {
            iter_type it = x.begin(); 
            for(int pos = 0; pos < i; ++pos)
                ++it;
            *it = v;
        } else {
            PyErr_SetString(PyExc_IndexError, "Index out of range");
            boost::python::throw_error_already_set();
        }
    }
};


template<class T>
void export_STLList(const char* typeName)
{
    using namespace boost::python;

    class_<std::list<T> >(typeName)
        .def("__len__", &std::list<T>::size)
        .def("clear", &std::list<T>::clear)
        .def("append", &listwrap<T>::add,
            with_custodian_and_ward<1,2>()) // to let container keep value
        .def("__getitem__", &listwrap<T>::get,
            return_value_policy<copy_non_const_reference>())
        .def("__setitem__", &listwrap<T>::set,
            with_custodian_and_ward<1,2>()) // to let container keep value
        .def("__delitem__", &listwrap<T>::del)
        .def("__contains__", &listwrap<T>::in)
        .def("__iter__", iterator<std::list<T> >())
        .def("index", &listwrap<T>::index);
}
typedef std::list<int> intlist;
export_STLList<int>("intlist");
typedef std::list intlist;
出口清单(“国际清单”);

如果单向(从C++到Python)包装足够,那么你可以从List中定义一个直接转换器——见我——只需根据需要更改类型,不要忘记。

您还可以返回一个方法:<代码> python::list < /C>(它本身包含<代码> python::list < /COD>与您的对象),它将迭代C++嵌套列表并从中生成本地Python列表,但它只在一种情况下工作。

对于双向转换,请查看我的文件(其中包含不同类型的双向转换器)——优点是可以获得本机python列表,缺点是复制对象。对于大型集合的双向转换,
indexing\u suite
无疑是一个不错的选择


还有
index\u suite\u v2
,据说它要好得多,包括直接支持
std::list
std::map
,但不幸的是,它的文档非常糟糕(上次我看的时候,大约是1.5年前),并且不是
boost::python
的正式部分。你的python代码片段无法工作。如果要将
CameraNode.getCameraInfo()
添加到
cameras
列表,请执行
cameras.append(CameraNode.getCameraInfo())
。如果您只需要这些信息,只需执行
camera=CameraNode.getCameraInfo()
,然后像
print camera.name
.tnx@agf那样访问它,但缺少更多信息。。。如果我照你说的做,我没有收到任何错误信息,但我的相机里也装满了
None
,这不是我想要的:)同时我发现:我知道它没有回答你的问题,这就是为什么我把它作为一条评论发布的原因。很好的例子@Aleksey:)我必须
typedef typename t::const_iterator
on
index()
由于问题。我仍然有这个错误
WrapHelper.cpp:In函数'void export_stlist(const char*)':WrapHelper.cpp:405:54:错误:模板参数的数目错误(1,应该是5)/usr/include/c++/4.5/bits/stl迭代器基类型。h:114:12:错误:为“模板结构std::迭代器”提供。
抱歉,已修复。它应该是.def(“iter”,iterator())而不是.def(“iter”,std::iterator())你有没有链接到indexing_suite_v2的链接?它是该网站的一部分,尽管与几年前的情况相反,它似乎并不十分活跃,而且网站language-binding.net也不太活跃