我有一个自定义类型,它基本上是带有额外函数的 C++ 布尔值。我需要通过 Python 访问我的 C++ 库,该框架基于 Boost。
目前我必须使用 int 而不是 bool,因为后端可以很好地从 int 转换为我的自定义类型。必要时我需要能够从 python 的 bool 转换为我的自定义 bool,反之亦然。
这是一些模仿我迄今为止所做的代码:
#include <boost/python.hpp>
using namespace boost::python;
class CustomBool
{
public:
CustomBool(bool b) : is_set(b) {}
operator bool() const { return is_set; };
private:
bool is_set{false};
};
struct Example
{
CustomBool get_CustomBool(bool x)
{
return CustomBool(x);
}
bool convert_custom(bool x)
{
return bool(CustomBool(x));
}
};
BOOST_PYTHON_MODULE(bptest)
{
implicitly_convertible<CustomBool, bool>();
implicitly_convertible<bool, CustomBool>();
Py_Initialize();
class_<Example>("Example")
.def("convert_custom", &Example::convert_custom)
.def("get_CustomBool", &Example::get_CustomBool);
}
当我在 Python 中使用它时,我得到以下信息:
>>> from bptest import Example
>>> ex = Example()
>>> ex.get_CustomBool(True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No to_python (by-value) converter found for C++ type: CustomBool
我找到了一些字符串转换示例,但我无法将他们的解决方案转移到我的(更简单?)问题上。
文档(https://www.boost.org/doc/libs/1_72_0/libs/python/doc/html/reference/to_from_python_type_conversion.html)对我也没有帮助,但也许对其他人有帮助?
解决此问题的一种方法是为 CustomBool 类定义自定义 to_python 转换器。这可以通过创建一个继承自 boost::python::to_python_converter 的结构并实现可转换和构造函数来完成。以下是如何做到这一点的示例:
#include <boost/python.hpp>
using namespace boost::python;
class CustomBool
{
public:
CustomBool(bool b) : is_set(b) {}
operator bool() const { return is_set; };
private:
bool is_set{false};
};
struct CustomBool_to_python_bool
{
static PyObject* convert(CustomBool const& b)
{
return boost::python::incref(boost::python::object(bool(b)).ptr());
}
};
struct Example
{
CustomBool get_CustomBool(bool x)
{
return CustomBool(x);
}
bool convert_custom(bool x)
{
return bool(CustomBool(x));
}
};
BOOST_PYTHON_MODULE(bptest)
{
to_python_converter<CustomBool, CustomBool_to_python_bool>();
Py_Initialize();
class_<Example>("Example")
.def("convert_custom", &Example::convert_custom)
.def("get_CustomBool", &Example::get_CustomBool);
}
我认为这会解决你的问题...