标签:python c-2 type-conversion boost boost-python
我正在为现有的C库编写一个包装器,它利用了列表,其中T是一个自定义结构.我被建议使用vector而不是list,但我试图避免修改库.
为了更好地理解场景,我做了一个简单的应用程序,使用列表作为注册to-python转换的代理(可以只读).
我当前的实现编译很好,python导入很好,可以创建对象,但是当我调用数据成员时,它会出错.
python shell输出:
In [1]: import my_list
In [2]: x = my_list.Bob()
In [3]: x.foos
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-2f015d13a87d> in <module>()
----> 1 x.foos
TypeError: No Python class registered for C++ class std::list<int, std::allocator<int> >
C档案:
#include <list>
#include <boost/python.hpp>
#include <boost/foreach.hpp>
#ifndef FOREACH
#define FOREACH BOOST_FOREACH
#endif
using namespace std;
using namespace boost::python;
template<typename T>
struct list_to_list
{
static PyObject* convert(const std::list<T>& src)
{
boost::python::list result;
FOREACH (const T& val, src)
{
result.append(val);
}
return incref(result.ptr());
}
};
struct Bob
{
std::list<int> foos;
};
BOOST_PYTHON_MODULE(my_list)
{
using namespace boost::python;
to_python_converter<std::list<int>, list_to_list<int> >();
class_<Bob>("Bob")
.def_readonly("foos", &Bob::foos)
;
}
我错过了什么吗?
解决方法:
如FAQ中所述,通过def_readonly(),def_readwrite()和add_property()以及默认策略公开的属性将不使用自定义转换器.要解决此问题,请使用add_property()替换def_readonly()和def_readwrite(),提供类型为boost::python::return_by_value
的boost::python::return_value_policy
.
在原始代码中,它将是:
BOOST_PYTHON_MODULE(my_list)
{
using namespace boost::python;
to_python_converter<std::list<int>, list_to_list<int> >();
class_<Bob>("Bob")
.add_property("foos", make_getter(&Bob_foos,
return_value_policy<return_by_value>()))
;
}
这是一个完整的例子:
#include <list>
#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
#include <boost/python.hpp>
namespace python = boost::python;
/// @brief Type to convert from an iterable to a Python list.
template <typename T>
struct list_to_list
{
static PyObject* convert(const std::list<T>& container)
{
python::list result;
BOOST_FOREACH(const T& value, container)
result.append(value);
return python::incref(result.ptr());
}
};
/// @brief mockup type.
struct Spam
{
Spam()
{
foos = boost::assign::list_of(1)(2)(3)(5);
}
std::list<int> foos;
};
BOOST_PYTHON_MODULE(example)
{
// Enable std::list<int> to Python list conversion.
python::to_python_converter<std::list<int>, list_to_list<int> >();
python::class_<Spam>("Spam")
.add_property("foo", python::make_getter(&Spam::foos,
python::return_value_policy<python::return_by_value>()))
;
}
由此产生的用法:
>>> import example
>>> spam = example.Spam()
>>> spam.foo
[1, 2, 3, 5]
标签:python,c-2,type-conversion,boost,boost-python 来源: https://codeday.me/bug/20190629/1324784.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。