如何使用pybind

时间:2019-07-29 15:03:08

标签: python-3.x pybind11

我正在使用pybind11在整数键和python对象之间实现映射。为了避免在对象之间存在循环引用(例如在自身中添加映射)时出现内存泄漏,通常会定义tp_traverse,但我看不到使用pybind进行此操作的任何方法。 这是一个示例:

#include <map>
#include <pybind11/pybind11.h>

namespace py = pybind11;


class MyMap {
public:
    typedef std::map<int, py::object> MapType;
    typedef typename MapType::iterator IteratorType;

    virtual py::object get(int key) {
      return _map[key];
    }

    virtual void put(int key, py::object value) {
      _map[key] = value;
      value.inc_ref();
    }

    void deleteItem(int key) {
      IteratorType it = _map.find(key);
      it->second.dec_ref();
      _map.erase(it);
    }

    ssize_t size() const {
        return _map.size();
    }

protected:
    MapType _map;
};

PYBIND11_MODULE(my_map, m) {
    py::class_<MyMap>(m, "MyMap")
    .def(py::init<>())
    .def("size", &MyMap::size)
    .def("delete_item", &MyMap::deleteItem)
    .def("get", &MyMap::get)
    .def("put", &MyMap::put);
}

这是我尝试做的简约版本。

我用python编写了一个执行以下操作的测试:

    def test_traverse(self):
        _map = MyMap()
        self.assertTrue(gc.is_tracked(_map))
        _map.put(1, 'test')
        _map.put(2048, 'foo')
        _map.put(4096, 'bar')
        self.assertEqual(len(gc.get_referents(_map.store)), 3)

但是_map对象没有引用对象。以我的理解,我应该做的是使MyMap的tp_traverse行为正确,但是我看不到这样做的方法。我尝试将keep_alive参数添加到def("put"调用中,但这似乎没有完成。我想念什么吗?还有其他方法可以使用pybind11完成吗?

0 个答案:

没有答案