1
我有一個Python類,它是從C++類派生的,並覆蓋了部分函數。 C++函數接收Python類的對象並將其存儲在向量中,因此GC類不應收集Python類。我嘗試了兩種不同的方法,但第一個不能編譯,第二個不會在運行時看到重寫(C++的函數被調用而不是Python類的函數)。請告訴我什麼是正確的做法。Boost Python:無法調用Python派生類中覆蓋的C++虛函數
的C++代碼:
class MyClass
{
public:
virtual void PureVirtual(int i) = 0;
virtual const char* VirtualWithDefaultImpl()
{
return "MyClass";
}
};
void MyFnc(boost::shared_ptr<MyClass> obj)
{
myVector.push_back(obj);
std::cout << obj->VirtualWithDefaultImpl() << std::endl;
obj->PureVirtual(0);
}
python封裝:
class MyClassWrap : public MyClass, wrapper<MyClass>
{
public:
MyClassWrap(PyObject* self) : m_self(self)
{
Py_INCREF(self);
}
MyClassWrap(PyObject* self, const MyClass& other) : MyClass(other), m_self(self)
{
Py_INCREF(self);
}
~MyClassWrap()
{
Py_DECREF(m_self);
}
virtual void PureVirtual(int i)
{
this->get_override("PureVirtual")(i);
}
virtual const char* VirtualWithDefaultImpl()
{
if (override f = this->get_override("VirtualWithDefaultImpl"))
return f();
return MyClass::VirtualWithDefaultImpl();
}
const char* DefaultVirtualWithDefaultImpl()
{
return this->MyClass::VirtualWithDefaultImpl();
}
private:
PyObject* m_self;
};
BOOST_PYTHON_MODULE(MyModule)
{
// First approach:
// Fails in compilation with error C2243: 'type cast' : conversion from
// 'MyClassWrap *' to 'boost::python::wrapper<T> *' exists, but is inaccessible
//class_<MyClassWrap, boost::shared_ptr<MyClassWrap>, boost::noncopyable>("MyClass")
// Second approach:
// Doesn't see the overrides at runtime
class_<MyClass, boost::shared_ptr<MyClassWrap>, boost::noncopyable>("MyClass")
.def("PureVirtual", pure_virtual(&MyClass::PureVirtual), args("i"))
.def("VirtualWithDefaultImpl", &MyClass::VirtualWithDefaultImpl,
&MyClassWrap::DefaultVirtualWithDefaultImpl);
def("MyFnc", &MyFnc, args("obj"));
}
的Python代碼:
class PythonDerived(MyModule.MyClass):
def PureVirtual(self, i):
print i
def VirtualWithDefaultImpl(self):
return 'PythonDerived'
MyModule.MyFnc(PythonDerived())
第二助跑的輸出。正如你所看到的MyClass函數調用,而不是PythonDerived功能:
MyClass
File "z:\tmp\tmp.py", line 11, in <module>
MyModule.MyFnc(PythonDerived())
TypeError: 'NoneType' object is not callable
非常感謝您的快速響應!我認爲你的修復可能是一個問題。 MyFnc接收到的共享指針不會阻止GC收集PythonDerived對象(請參見[link](https://wiki.python.org/moin/boost.python/HowTo)一節)「在Python中擴展的C++對象的所有權「)。正如我在我的原始問題中提到的,PythonDerived對象由MyFnc存儲在一個向量中供將來使用,因此必須防止GC對PythonDerived對象的收集。 – user3240228