С pybind11, как мне установить владение основной памятью для объекта array_t? - PullRequest
1 голос
/ 17 мая 2019

Я пытаюсь сделать встраивание Python в приложение C ++ с pybind11.

Я создаю 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, что ему принадлежит память?

1 Ответ

0 голосов
/ 17 мая 2019

Если вы просто не передадите указатель данных, 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
...