使用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; }
这可能吗??我应该改用add_属性吗?我不认为我可以为每个结构创建一个类。这个设计在我只使用C++的时候是有意义的,但是现在我必须把它包起来,我变得越来越困惑。 任何关于用boost.python以通用方式包装std::list的建议都会被广泛接受 编辑: 我将在此处添加我发现有用的链接:使用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
是否必须是
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
onindex()
由于问题。我仍然有这个错误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也不太活跃