python - 将 C++ boost::variant 暴露给 Python 时出错
问题描述
我正在编写一个 Python 模块,我需要在其中访问 C++ 库。我正在使用 Boost-Python 将 C++ 库中实现的功能公开给 Python。
我必须将 boost::variant < bool, unsigned int, std::string, boost::asio::ip::address, std::vector> 从 C++ 暴露给 Python 模块。
我编写了一个实现该功能的代码,但出现错误。如果有人帮助我解决问题,我将不胜感激。
#include <boost/variant.hpp>
#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/init.hpp>
#include <boost/python/module.hpp>
#include <boost/python/object.hpp>
using myvariant = boost::variant<bool,int,std::string>;
struct variant_wrapper
{
struct variant_to_object : boost::static_visitor<PyObject *>
{
static result_type convert(myvariant const &v)
{
return apply_visitor(variant_to_object(), v);
}
template<typename T>
result_type operator()(T const &t) const
{
return boost::python::incref(boost::python::object(t).ptr());
}
};
myvariant variant_;
variant_wrapper ()
{}
variant_wrapper (myvariant& variant) : variant_(variant)
{}
void setAsBool(bool value)
{
variant_ = value;
}
void setAsString(const std::string& value)
{
variant_ = value;
}
boost::python::object getValue()
{
return variant_to_object::convert(variant_);
}
};
myvariant make_variant() { return myvariant(); }
BOOST_PYTHON_MODULE(pyintf) {
using namespace boost::python;
class_<variant_wrapper>("variant_wrapper", init<>())
.def("setAsBool",&variant_wrapper::setAsBool)
.def("setAsString",&variant_wrapper::setAsString)
.def("getValue", &variant_wrapper::getValue)
;
def("make_variant", make_variant);
to_python_converter<myvariant, variant_wrapper::variant_to_object>();
}
我收到以下错误。我进行了搜索,但没有一个解决方案在这里有效。
pyintf.cpp:132:51: error: could not convert ‘variant_wrapper::variant_to_object::convert((*(const myvariant*)(&((variant_wrapper*)this)->variant_wrapper::variant_)))’ from ‘boost::static_visitor<_object*>::result_type {aka _object*}’ to ‘boost::python::api::object’
return variant_to_object::convert(variant_);
解决方案
下面是一种在 Python Boost 中公开 C++ 变体的方法是:
- 包裹在一个类中
- 代码 SET 和 GET 方法
- 在 Python Boost 模块中公开类。
包括
using namespace std;
boost::variant<int, string, bool> v;
typedef boost::variant<int, string, bool> myvar;
class VariantClass
{
public:
myvar x = "hello";
myvar y = 20;
myvar z = false;
void setString(string n){
x = n;
}
void setInt(int n){
y = n;
}
void setBool(bool n){
z = n;
}
string getString(){
string s = boost::get<string>(x);
return s;
}
int getInt(){
int i = boost::get<int>(y);
return i;
}
bool getBool(){
bool b = boost::get<bool>(z);
return b;
}
string greet() { return "Hello World Test!"; }
};
//using namespace boost::python;
BOOST_PYTHON_MODULE(bpv)
{
using namespace boost::python;
class_<VariantClass>("VariantClass", init<>())
.def("setString", &VariantClass::setString)
.def("setInt", &VariantClass::setInt)
.def("setBool", &VariantClass::setBool)
.def("getString", &VariantClass::getString)
.def("getInt", &VariantClass::getInt)
.def("getBool", &VariantClass::getBool)
.def("greet", &VariantClass::greet);
}
推荐阅读
- pyqgis - pyQGIS 自定义对比度增强功能
- c# - 是否可以使用 C# 使用 selenium WebDriver 打开边缘开发人员工具?
- ruby-on-rails - Rails - 如果 CSV 中的值为 TRUE,如何呈现内容?
- visual-studio-code - 在带有 Rust 的 VSCode 中,如何将其他参数传递给货物测试?
- scala - java.lang.NoSuchMethodError: org.apache.spark.sql.catalyst.analysis.FunctionRegistry.clone()Lorg/apache/spark/sql/catalyst/analysis/FunctionRegistry
- javascript - 即使在 useEffect 中设置后,State 也会返回一个空数组
- batch-file - 将基于文件名的 pdf 与同名子文件夹中的 pdf 合并
- css - 闪亮:对齐 inputPanel 和 wellPanel,或使用其他小部件
- django - Django 在 oauth 回调后执行操作
- openmdao - OpenMDAO 的 SNOPT