导出C++类(纯虚函数和虚函数)
大致做法就是为class写一个warp,通过get_override方法检测虚函数是否被重载了,如果被重载了调用重载函数,否则调用自身实现,最后导出的时候直接导出warp类,但是类名使用class,析构函数不需要导出,因为它会被自动调用
纯虚函数
编写C++函数实现
1$ vim virt.h 2#include <iostream> 3#include <boost/python/wrapper.hpp> 4 5// 用class会出现编译问题, 不知道是不是和boost::python里面的class产生了冲突 6struct Base 7{ 8 virtual ~Base() { std::cout << "Base destructor" << std::endl; }; 9 virtual int f() = 0; 10}; 11 12struct BaseWrap : Base, boost::python::wrapper<Base> 13{ 14 int f() 15 { 16 return this->get_override("f")(); 17 } 18};
编写Boost.Python文件
1$ vim virt_wrapper.cpp 2#include <boost/python/module.hpp> 3#include <boost/python/class.hpp> 4#include <boost/python/pure_virtual.hpp> 5#include "virt.h" 6 7using namespace boost::python; 8using namespace boost::python::detail; 9 10BOOST_PYTHON_MODULE_INIT(virt_ext) 11{ 12 class_<BaseWrap, boost::noncopyable>("Base") 13 .def("f", pure_virtual(&Base::f)); 14}
运行python测试库文件
1$ python 2>>> import virt_ext 3>>> def f(): 4... o = virt_ext.Base() 5... 6>>> f() 7Base destructor
虚函数
编写C++函数实现
1$ vim virt.h 2#include <boost/python/wrapper.hpp> 3#include <boost/python/call.hpp> 4 5struct Base 6{ 7 virtual ~Base() { std::cout << "Base destructor" << std::endl; }; 8 virtual int f() = 0; 9}; 10 11struct BaseWrap : Base, boost::python::wrapper<Base> 12{ 13 int f() 14 { 15 return this->get_override("f")(); 16 } 17}; 18 19struct Derived: Base 20{ 21 virtual ~Derived() { std::cout << "Derived destructor" << std::endl; } 22 virtual int f() { std::cout << "Override by Derived" << std::endl; return 0; } 23}; 24 25struct DerivedWrap : Derived, boost::python::wrapper<Derived> 26{ 27 int f() 28 { 29 if (boost::python::override func = this->get_override("f")) 30 return func(); 31 return Derived::f(); 32 } 33};
编写Boost.Python文件
1$ vim virt_wrapper.cpp 2#include <boost/python/module.hpp> 3#include <boost/python/class.hpp> 4#include <boost/python/pure_virtual.hpp> 5#include "virt.h" 6 7using namespace boost::python; 8using namespace boost::python::detail; 9 10BOOST_PYTHON_MODULE_INIT(virt_ext) 11{ 12// 可以导出Base也可以不导出Base 13// class_<BaseWrap, boost::noncopyable>("Base") 14// .def("f", pure_virtual(&Base::f)); 15 class_<DerivedWrap, boost::noncopyable>("Derived") 16 .def("f", &Derived::f); 17}
运行python测试库文件
1>>> import virt_ext 2>>> b = virt_ext.Base() 3>>> d = virt_ext.Derived() 4>>> d.f() 5Override by Derived 60 7>>> b.f() 8Traceback (most recent call last): 9 File "<stdin>", line 1, in <module> 10RuntimeError: Pure virtual function called 11>>> exit() 12Base destructor 13Derived destructor 14Base destructor