Boost Python官方样例(三)

导出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
posted @ 2018-05-25 11:06  银魔术师  阅读(1733)  评论(0编辑  收藏  举报