Pybind11: создать и вернуть массив numpy со стороны C++

Как создать массив numpy со стороны C++ и передать его python?

Я хочу, чтобы Python выполнял очистку, когда возвращаемый массив больше не используется Python.

Сторона C++ не будет использовать delete ret; для освобождения памяти, выделенной new double[size];.

Правильно ли следующее?

#include "pybind11/pybind11.h"
#include "pybind11/numpy.h"

namespace py = pybind11;

py::array_t<double> make_array(const py::ssize_t size) {
    double* ret = new double[size];
    return py::array(size, ret);
}

PYBIND11_MODULE(my_module, m) {
    .def("make_array", &make_array,
         py::return_value_policy::take_ownership);
}

person R zu    schedule 08.03.2018    source источник
comment
Я должен использовать numpy вместо собственного интерфейса pybind11, потому что я использую структурированный массив numpy.   -  person R zu    schedule 08.03.2018


Ответы (1)


Вы совершенно правы. Немного лучшее решение ниже.

#include "pybind11/pybind11.h"
#include "pybind11/numpy.h"

namespace py = pybind11;

py::array_t<double> make_array(const py::ssize_t size) {
    // No pointer is passed, so NumPy will allocate the buffer
    return py::array_t<double>(size);
}

PYBIND11_MODULE(my_module, m) {
    .def("make_array", &make_array,
         py::return_value_policy::move); // Return policy can be left default, i.e. return_value_policy::automatic
}
person S.M.    schedule 08.03.2018
comment
хм. И это не сделает копию? Я проверяю, есть ли у py::array_t конструктор перемещения... Кажется, он есть здесь: " rel="nofollow noreferrer">github.com/pybind/pybind11/blob/ - person R zu; 08.03.2018
comment
Конечно, он не сделает копию из-за оптимизации возвращаемого значения и копирования. - person S.M.; 08.03.2018
comment
Кастинг для py::return_value_policy::move находится здесь: github.com/pybind /pybind11/blob/ Спасибо. - person R zu; 08.03.2018
comment
Очень бы хотелось, чтобы они говорили об этом в официальной документации... - person R zu; 08.03.2018
comment
Инициализирует ли py::array_t только что выделенный буфер? Или мы должны инициализировать его сами? - person John; 25.11.2020