指向外部托管(例如Python)资源的C ++智能指针?

时间:2018-12-14 21:14:22

标签: python c++ pybind11

在C ++中是否有指向其他人管理的资源的智能指针?我正在使用pybind11如下包装C ++代码。

    class B {};
    class A {
      public:
        // original C++ class interface
        A(std::shared_ptr<B> pb) : mb(pb){}
        // have to add this for pybind11, since pybind11 doesn't take shared_ptr as argument.
        A(B * pb):A(std::shared_ptr<B>(pb)){}
      private:
        std::shared_ptr<B> mb;
    }
    namespace py = pybind11;
    PYBIND11_MODULE(test, m)
    {
       py::class_<B>(m, "B")
       .def(py::init<>());

       py::class_<A>(m, "A")
       .def(py::init<B *>());
    }

然后在python中,按如下方式使用它们:

    b = B()
    a = A(b)

这很好,只要我不知道。当我在python中删除a时,我在C ++的“ A”中创建的shared_ptr mb将尝试破坏B对象,该对象由Python管理并崩溃。因此,我的问题是C ++中是否存在一些不会从原始指针获取所有权的智能指针? weak_ptr无法正常工作,因为我仍然必须创建一个shared_ptr。

1 个答案:

答案 0 :(得分:1)

Pybind11在幕后使用唯一的指针来管理C ++对象,因为它认为C ++对象拥有该对象,并且每当Python包装对象被释放时,都应释放该对象。但是,您正在与C ++代码库的其他部分共享此指针。这样,您需要使用B类的Python包装器来使用共享指针管理B的实例。您可以在class_模板中执行此操作。例如。

PYBIND11_MODULE(test, m)
{
   py::class_<B, std::shared_ptr<B> >(m, "B")
   .def(py::init<>());

   py::class_<A>(m, "A")
   .def(py::init<std::shared_ptr<B> >());
}

https://pybind11.readthedocs.io/en/stable/advanced/smart_ptrs.html#std-shared-ptr