【问题标题】:Errors in exposing C++ boost::variant to Python将 C++ boost::variant 暴露给 Python 的错误
【发布时间】:2019-02-02 23:41:12
【问题描述】:

我正在编写一个 Python 模块,我需要在其中访问 C++ 库。我正在使用 Boost-Python 将 C++ 库中实现的功能公开给 Python。

我必须将 boost::variant 从 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 c++11 boost-python


    【解决方案1】:

    以下是一种在 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);
    }
    

    【讨论】:

    • 我还需要公开 boost::asio::ip::address、std::vector 作为 boost::variant 的一部分。我已经包含了 boost::asio::ip::address 的代码。 vartype ipa=“127.0.0.1”;其中 vartype 是我们的变体类型。我们需要在 VariantClass string getIPAddress(){ return boost::get&lt;boost::asio::ip::address&gt;(ipa).to_string(); } void setIPAddress(string iparg){ ipa = boost::asio::ip::address::from_string(iparg); } 中包含以下方法。在 BOOST_PYTHON_MODULE().def("getIPAddress", &amp;VariantClass::getIPAddress).def("setIPAddress", &amp;VariantClass::setIPAddress) .
    【解决方案2】:

    根据the Boost.Python manual,您使用boost::python::handle&lt;&gt;()PyObject*(您的convert 函数返回)构造一个boost::python::object。当我用此代码替换您的 getValue() 函数时,它会编译:

    return boost::python::object(
        boost::python::handle<>(
            variant_to_object::convert(variant_)));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      • 2016-12-18
      相关资源
      最近更新 更多