Расширение C ++ до Python - безопасный доступ к памяти и структура памяти - PullRequest
1 голос
/ 07 января 2020

Я расширяю код python с помощью функций c ++, работающих с массивами Numpy (очень большой). Из-за устаревшей версии у меня в настоящее время есть функции API PyBind и Python, как для Python 3.6, так и выше. Как только я получу доступ к памяти через ptr, я бы хотел быть уверенным, что макет памяти точно соответствует массиву c ++ под этим ptr. Я обнаружил, что в обоих случаях транспонированный массив имеет одинаковое содержимое в ptr. Я также обнаружил, что подмассивы, отправляемые через Python API, дают в c ++ точно такой же ptr, как если бы это был полный массив. В ходе разработки и тестирования я также наблюдал более странные примеры, которые, я считаю, но больше не могу их воспроизводить. Я не могу найти никаких рецептов на inte rnet до сих пор. Мое решение состоит в том, чтобы сделать копию всех входных массивов в Python, например, f (a.copy (), b.copy ())

Кажется, это работает хорошо. Это оптимальное / достаточное решение? У меня нет никаких ограничений на то, как были созданы входные массивы. Транспонировать, подмассировать, изменять форму, в любых сочетаниях.

1 Ответ

2 голосов
/ 08 января 2020

С pybind11 вы можете использовать флаг py::array::c_style, как описано в ссылке Мэтта Эдинга. Numpy's C API обеспечивает почти такую ​​же функциональность через флаг NPY_ARRAY_C_CONTIGUOUS. В любом случае массив будет скопирован неявно, если это необходимо для удовлетворения требований макета; если вы предпочитаете отклонять такие аргументы (чтобы избежать молчаливой неэффективности), вам придется проверить массив flags самостоятельно.

...