使用PYBIND11,如何为Array_t对象设置基础内存的所有权

With pybind11, how do I set ownership of the underlying memory for an array_t object?

本文关键字:设置 对象 内存 所有权 PYBIND11 Array 使用      更新时间:2023-10-16

我正在尝试使用PYBIND11进行python嵌入。

我正在创建一个具有以下功能的array_t

template<class T>
py::array_t<T> create_matrix(size_t width, size_t height, T* data_ptr = nullptr)
{
    auto b = py::buffer_info(
        data_ptr,
        sizeof(T), //itemsize
        py::format_descriptor<T>::format(),
        2, // ndim
        std::vector<size_t> { width, height }, // shape
        std::vector<size_t> {height * sizeof(T), sizeof(T)} // strides
    );
    return py::array_t<T>(b);
}

如果我使用这样的功能:

float* raw_array_data = new float[4];
{
    py::array_t<float> arr_f2 = create_matrix<float>(2, 2, raw_array_data);
    ...
}
// Use raw_data_array here.

raw_array_data仍在arr_f2的范围之外可用。如果以这种方式构造,array_t似乎起作用为"视图"。

但是,在某些情况下,我可能希望array_t拥有提供给create_matrix的内存的所有权。我该如何告诉array_t它拥有内存?

如果您根本不传递数据指针,numpy将为您分配内存。如果您无法控制分配,则必须自己销毁它(因为Numpy不会知道如何分配数据,并且似乎没有一种通过Deallocator函数的方法(:

{
    // arr_f2 will get numpy to allocate 4 floats
    py::array_t<float> arr_f2 = create_matrix<float>(2, 2);
    ...
}
// and Python will deallocate them when it gets decrefd
float* raw_array_data = new float[4];
{
    std::unique_ptr<float[]> raw_array_data_destructor(raw_array_data);
    py::array_t<float> arr_f2 = create_matrix<float>(2, 2, raw_array_data);
}
// And std::unique_ptr<float[]>::~unique_ptr will delete[] the data