提升python和虚拟类

时间:2016-11-09 13:54:19

标签: c++ virtual boost-python

我正在努力将一些现有的C ++代码暴露给Python。

我有一个虚拟课程:

class SomeVirtualClass {
public:
    SomeVirtualClass();
    virtual ~SomeVirtualClass();
    virtual SomeVirtualClass *clone() const = 0;
    virtual SomeVirtualClassType getType() const = 0;
    // SomeVirtualClassType is a descriptive enum
    virtual std::string getSomeString() const = 0;
private:
    //some other things here
}

和一个使用虚拟类型的类:

class A {
    public:
        SomeVirtualClass getThisThing();
    }

我需要能够在python中使用A中的getThisThing。该方法可以返回从SomeVirtualClass派生的许多类中的一个。使用boost doc和几个类似的stackoverflow问题,我想出了:

namespace bp = boost::python
class SomeVirtualClassWrap : public SomeVirtualClass,
                         public bp::wrapper<SomeVirtualClass> {
    public:
    std::string getSomeString() {
        return this->get_override("getSomeString")();
    }

    SomeVirtualClass *clone() {
        return this->get_override("clone")();
    }

    SomeVirtualClassType getType() {
        return this->get_override("getType")();   
    }
};

作为虚拟类的包装器,并且:

bp::class_ <SomeVirtualClassWrap, boost::noncopyable>("SomeVirtualClass", no_init)
        .def("GetSomeString", bp::pure_virtual(&SomeVirtualClass::getSomeString))
        .def("Clone", bp::pure_virtual(&SomeVirtualClass::clone))
        .def("GetType", bp::pure_virtual(&SomeVirtualClass::getType));

蟒蛇曝光。

参考A类也暴露出来:

bp::class_<A>("A") {
    .def("GetThisThing", &A::getThisThing)
}

当我尝试编译时,我得到:

error: cannot declare field 'boost::python::objects::value_holder<SomeVirtualClassWrap>::m_held' to be of abstract type 'SomeVirtualClassWrap'
src/lib/objects/sub_mtrl/rebarmodule.c:412:7: note:   because the following virtual functions are pure within 'SomeVirtualClassWrap':
ThisIsAHeader.h:42:27: note:     virtual SomeVirtualClass* SomeVirtualClass::clone() const
ThisIsAHeader.h:43:30: note:     virtual SomeVirtualClassType SomeVirtualClass::getType() const
ThisIsAHeader.h:44:25: note:     virtual std::string SomeVirtualClass::getSomeString() const
In file included from tools/boost-for-sds2-2016/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47:0,
                 from tools/boost-for-sds2-2016/include/boost/python/object/value_holder.hpp:50,
                 from tools/boost-for-sds2-2016/include/boost/python/object/class_metadata.hpp:11,
                 from tools/boost-for-sds2-2016/include/boost/python/class.hpp:23,
                 from tools/boost-for-sds2-2016/include/boost/python.hpp:18

我需要能够从Python调用A.GetThisThing()并处理该对象。如果可能的话,我宁愿保留现有代码。

编辑:根据评论,我在python曝光代码中添加了no_init,清除了关于纯方法的错误。现在我离开了:

error: no match for call to '(const boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning<SomeVirtualClass*>) (SomeVirtualClass*)

编辑:从Python曝光中删除* clone方法清除了错误。结果我不需要那个。只是处理转换错误。

1 个答案:

答案 0 :(得分:1)

根据Luka Rahne的评论,添加no_init修复了编译错误:

bp::class_ <SomeVirtualClassWrap, boost::noncopyable>("SomeVirtualClass", no_init)
        .def("GetSomeString", bp::pure_virtual(&SomeVirtualClass::getSomeString))
        .def("Clone", bp::pure_virtual(&SomeVirtualClass::clone))
        .def("GetType", bp::pure_virtual(&SomeVirtualClass::getType));

特别呼叫到下午同样。