導出C++類(純虛函數和虛函數)
大致做法就是為class寫一個warp,通過get_override方法檢測虛函數是否被重載了,如果被重載了調用重載函數,否則調用自身實現,最后導出的時候直接導出warp類,但是類名使用class,析構函數不需要導出,因為它會被自動調用
純虛函數
編寫C++函數實現
$ vim virt.h
#include <iostream>
#include <boost/python/wrapper.hpp>
// 用class會出現編譯問題, 不知道是不是和boost::python里面的class產生了沖突
struct Base
{
virtual ~Base() { std::cout << "Base destructor" << std::endl; };
virtual int f() = 0;
};
struct BaseWrap : Base, boost::python::wrapper<Base>
{
int f()
{
return this->get_override("f")();
}
};
編寫Boost.Python文件
$ vim virt_wrapper.cpp
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/pure_virtual.hpp>
#include "virt.h"
using namespace boost::python;
using namespace boost::python::detail;
BOOST_PYTHON_MODULE_INIT(virt_ext)
{
class_<BaseWrap, boost::noncopyable>("Base")
.def("f", pure_virtual(&Base::f));
}
運行python測試庫文件
$ python
>>> import virt_ext
>>> def f():
... o = virt_ext.Base()
...
>>> f()
Base destructor
虛函數
編寫C++函數實現
$ vim virt.h
#include <boost/python/wrapper.hpp>
#include <boost/python/call.hpp>
struct Base
{
virtual ~Base() { std::cout << "Base destructor" << std::endl; };
virtual int f() = 0;
};
struct BaseWrap : Base, boost::python::wrapper<Base>
{
int f()
{
return this->get_override("f")();
}
};
struct Derived: Base
{
virtual ~Derived() { std::cout << "Derived destructor" << std::endl; }
virtual int f() { std::cout << "Override by Derived" << std::endl; return 0; }
};
struct DerivedWrap : Derived, boost::python::wrapper<Derived>
{
int f()
{
if (boost::python::override func = this->get_override("f"))
return func();
return Derived::f();
}
};
編寫Boost.Python文件
$ vim virt_wrapper.cpp
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/pure_virtual.hpp>
#include "virt.h"
using namespace boost::python;
using namespace boost::python::detail;
BOOST_PYTHON_MODULE_INIT(virt_ext)
{
// 可以導出Base也可以不導出Base
// class_<BaseWrap, boost::noncopyable>("Base")
// .def("f", pure_virtual(&Base::f));
class_<DerivedWrap, boost::noncopyable>("Derived")
.def("f", &Derived::f);
}
運行python測試庫文件
>>> import virt_ext
>>> b = virt_ext.Base()
>>> d = virt_ext.Derived()
>>> d.f()
Override by Derived
0
>>> b.f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Pure virtual function called
>>> exit()
Base destructor
Derived destructor
Base destructor