使用Boost.Python将Python对象的所有权转移到C ++代码

时间:2017-10-27 18:11:13

标签: python c++ boost boost-python

我有一个抽象类Shape(来自C ++代码),我为它做了一个包装器,所以我可以从Python继承这个抽象类。除了一些内存管理问题,一切都很好。在仍然存在ShapeWrapper C ++对象的情况下,Python对象被创建和销毁。基本上对象被破坏,因为在Python中没有对它的引用,但是在C ++中有对包装类的引用所以我的想法是wrapper类增加了初始化时的引用计数并且会减少计数C ++包装器类ShapeWrap被破坏时的析构函数。但似乎这并没有发生在这里。这是一些代码:

Shape类(用C ++编写):

struct Shape {
    virtual inline string get_name() const = 0;
};

ShapeWrap类:

struct ShapeWrap : public Shape, public wrapper<Shape> {
    string get_name() const override {
       if (auto py_func = this->get-override("get_name")) {
            return py_func();
       }
       return "Default String";
    }
}

我用这种方式定义类:

class_<ShapeWrap, shared_ptr<ShapeWrap>, boost::noncopyable>("Shape")
     .def("get_name", pure_virtual(&Shape::get_name));

现在我在这里有一个小功能来取一个Shape并打印出它的名字:

void print_name(shared_ptr<ShapeWrap> shape) {
    cout << shape->get_name() << endl;
}

在Python的土地上,我这样做:

class Circle(Shape):
    def __init__(self):
       super(Circle, self).__init__()
       print('Created')
    def __del__(self):
       print('Destroyed')
    def get_name(self):
       return "blah"

print_name(Circle())

这就是我得到的

Created
blah
Destroyed

但如果我这样做:

shared_ptr<ShapeWrap> create_shape(const object& cb) {
     return extract<shared_ptr<ShapeWrap>>(cb())();
}

在Python中执行此操作:

print_name(create_shape(lambda: Circle()))

我得到了

Created
Destroyed
RuntimeError: Pure virtual function called

如果我在ShapeWrap的构造函数和析构函数中添加cout,我会得到这个

C++ Constructor
Created
Destroyed
RuntimeError: Pure virtual function called
C++ Destructor

请注意,纯虚拟事物的发生是因为Python对象被销毁,因此没有覆盖方法,因此包装器会调用基本实现,这是一种引发RuntiemError异常的方法。

0 个答案:

没有答案