Boost Python没有为std :: string找到to_python转换器 [英] Boost Python No to_python converter found for std::string
问题描述
因此,我正在尝试创建一个to_python转换器,该转换器将允许我从公开的函数返回boost :: optional,如果设置了optional,则将其视为T;否则将其视为None.基于我在 C ++ Sig 上找到的帖子中,我编写了以下代码.
So, I am trying to create a to_python converter that will allow me to return a boost::optional from an exposed function and have it treated as T if the optional is set and None if not. Based on a post I found on C++Sig, I wrote the following code.
template<typename T>
struct optional_ : private boost::noncopyable {
struct conversion {
static PyObject* convert(boost::optional<T> const& value) {
if (value) {
return boost::python::to_python_value<T>()(*value);
}
Py_INCREF(Py_None);
return Py_None;
}
};
explicit optional_() {
boost::python::to_python_converter<boost::optional<T>, conversion>();
}
};
据我所知,它可用于转换可选内容,但是python引发以下异常"TypeError:找不到C ++类型的to_python(按值)转换器:std :: string".我知道C ++能够将字符串转换为python,因为我的大多数公开函数都返回字符串.为什么boost :: python :: to_python_value无法识别它,我该如何利用它具有的任何转换器?
As far as I can tell, it works for converting the optionals, but python throws the following exception "TypeError: No to_python (by-value) converter found for C++ type: std::string". I know that C++ is able to convert strings to python since most of my exposed functions return strings. Why doesn't boost::python::to_python_value recognize it, and how can I utilize whatever converter it has?
Fixed by changing to the following (based on this article):
template<typename T>
struct optional_ : private boost::noncopyable {
struct conversion {
static PyObject* convert(boost::optional<T> const& value) {
using namespace boost::python;
return incref((value ? object(*value) : object()).ptr());
}
};
explicit optional_() {
boost::python::to_python_converter<boost::optional<T>, conversion>();
}
};
现在只做其他版本,以便它更干净,更好地工作.
Now to just do the other version so that it is cleaner and works better.
推荐答案
好吧,这是基于原始C ++ sig帖子的来回可选转换器的全部内容,但重写后使用了高级boost.python API(对不起,很奇怪间距).
Ok here is the entire to and from optional converter based on the original C++ sig post but rewritten to use the high level boost.python API (sorry about the weird spacing).
template<typename T>
struct optional_ : private boost::noncopyable
{
struct conversion :
public boost::python::converter::expected_from_python_type<T>
{
static PyObject* convert(boost::optional<T> const& value) {
using namespace boost::python;
return incref((value ? object(*value) : object()).ptr());
}
};
static void* convertible(PyObject *obj) {
using namespace boost::python;
return obj == Py_None || extract<T>(obj).check() ? obj : NULL;
}
static void constructor(PyObject *obj,
boost::python::converter::rvalue_from_python_stage1_data *data)
{
using namespace boost::python;
void *const storage =
reinterpret_cast<
converter::rvalue_from_python_storage<boost::optional<T> >*
>(data)->storage.bytes;
if(obj == Py_None) {
new (storage) boost::optional<T>();
} else {
new (storage) boost::optional<T>(extract<T>(obj));
}
data->convertible = storage;
}
explicit optional_() {
using namespace boost::python;
if(!extract<boost::optional<T> >(object()).check()) {
to_python_converter<boost::optional<T>, conversion, true>();
converter::registry::push_back(
&convertible,
&constructor,
type_id<boost::optional<T> >(),
&conversion::get_pytype
);
}
}
};
这篇关于Boost Python没有为std :: string找到to_python转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!