Очевидно, что довольно сложно «объяснить, почему что-то [...] не сработает», потому что в конечном итоге это просто проектное решение, которое могло быть принято по-другому. Но:
Представления памяти Cython сделаны довольно глупыми. Все, что они делают, - это предоставляют какой-то приятный синтаксис для доступа к памяти чего-то, что реализует буферный протокол Python , а затем имеют чуть-чуть дополнительного синтаксиса, чтобы вы могли делать такие вещи, как получение 1D-памяти в виде указателя.
Кроме того, просмотр памяти в целом что-то оборачивает. Когда вы создаете cdef int[:, :] arr_view
, оно недействительно, пока вы не сделаете arr_view = something
. Попытки присвоить его части бессмысленны, поскольку (а) он делегировал бы назначение объекту, который оборачивает, используя буферный протокол, и (б) как именно будет работать назначение, будет зависеть от того, какой формат протокола буфера вы оборачиваете,То, что вы сделали , может быть верным, если обернуть «косвенный» объект протокола буфера, но не имеет смысла, если обернуть непрерывный массив. Поскольку arr_view
может быть упаковкой, либо компилятор Cython должен рассматривать это как ошибку.
Вопрос, который вы связываете с , реализует буферный протокол и поэтому является правильным способом реализации такого рода. массива. То, что вы пытаетесь сделать, - это взять дополнительный синтаксис, который дает одномерное представление памяти из указателя, и принудительно включить его в часть двухмерного обзора памяти в смутной надежде, что это может сработать. Для этого требуется много логики, выходящей далеко за рамки того, для чего предназначено представление памяти Cython.
Вероятно, стоит сделать пару дополнительных замечаний:
Просмотр указателей в памяти не справляется с освобождением указателей (поскольку для них было бы практически невозможно угадать, что вы хотите). Вы должны справиться с этой логикой. Ваш текущий дизайн будет утечка памяти, если он работает. В проекте, который вы связали с классом упаковки, это может быть реализовано в __dealloc__
(хотя в этом ответе это не показано) и, следовательно, намного лучше.
Мое личное мнение таково "рваные массивы "(2D-массивы указателей на указатели) ужасны. Они требуют много распределения и освобождения. Есть много возможностей их наполовину инициализировать. Доступ к ним требует нескольких уровней косвенности и поэтому медленный. Единственное, что им нужно, это то, что они обеспечивают синтаксис arr[idx1][idx2]
на C. В общем, я очень предпочитаю подход Numpy для выделения одномерного массива и использования shape / step для определения, куда индексировать. (Очевидно, что если вы оборачиваете существующую библиотеку, то, возможно, вы не сможете выбрать ее ...)