2016-11-09 101 views
0

我正在將一些現有的C++代碼暴露給Python。Boost 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中使用getThisThing從A。該方法可以返回從SomeVirtualClass派生的許多類中的一個。使用升壓doc和幾個類似計算器的問題,我想出了:

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()和手柄物體。如果可能的話,我寧願保留現有的代碼。

編輯:根據評論,我添加了no_init到python暴露代碼和關於純方法的錯誤清除了。現在我剩下了:

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

編輯:從Python暴露中刪除*克隆方法清除了錯誤。原來我反正不需要那個。只是在處理轉換錯誤。

+1

你嘗試過包裝:'bp :: class_ (「SomeVirtualClass」,no_init)'? –

+0

謝謝!這清除了其中的一個錯誤,結果發現了另一個錯誤。當您的終端被淹沒時,很難看到有什麼。 :/ – Lunchbox

+1

剛剛發佈了一個工作示例[這裏](http://stackoverflow.com/questions/40451586/creating-new-classes-members-at-run-time-in-scripting-languages-used-in-c/ 40497466#40497466),看一看。 –

回答

0

按盧卡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)); 

特別喊出N.M.以及。