首页 > 解决方案 > pybind11::keep_alive 的逆向 API 是什么?

问题描述

使用 pybind11::keep_alive 构造可以确保附加到 List 的对象至少与 List 本身一样长。

引用pybind11::keep_alive的文档,

考虑以下示例:这里,列表追加操作的绑定代码将新添加元素的生命周期与底层容器联系起来:

py::class_<List>(m, "List")
    .def("append", &List::append, py::keep_alive<1, 2>());

同样,如何在删除 API 上解开附加对象的生命周期?

py::class_<List>(m, "List")
    .def("append", &List::append, py::keep_alive<1, 2>())
    .def("remove", &List::remove, ... /* What goes here? */);

澄清一下,removeAPI 将要移除的元素作为参数并从列表中移除元素。因此,在删除成功后将已删除对象的生命周期与列表绑定是没有意义的。

以下方法可以像这样减少python对象上的引用计数

.def("remove", [](List& list, py::object obj) {
        list.remove(obj.cast<CppObject*>());
        obj.dec_ref();
    });

不起作用,因为当 List python 对象被垃圾收集时,pybind11 将尝试再次减少引用计数。

是否有与 pybind11::keep_alive 相反的解决方案?

提前致谢!

将 C++17 与 pybind11 v2.6.1 一起使用。

标签: c++pybind11

解决方案


浏览完pybind11的issues后,发现下面的feature request https://github.com/pybind/pybind11/issues/1708解决了一个和我描述的类似的问题。


推荐阅读