首页 > 解决方案 > 将 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_);

标签: pythonc++11boost-python

解决方案


下面是一种在 Python Boost 中公开 C++ 变体的方法是:

  1. 包裹在一个类中
  2. 代码 SET 和 GET 方法
  3. 在 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);
}

推荐阅读