Вопрос

РЕДАКТИРОВАТЬ:Перечитав свой первоначальный вопрос, я очень быстро понял, что он очень плохо сформулирован, двусмыслен и слишком запутан, чтобы когда-либо получить достойный ответ.Вот что я получаю за то, что задал вопрос в конце обеденного перерыва.Надеюсь, это будет яснее:

Я пытаюсь представить простую структуру C для Python (3.x) как PyBuffer, чтобы я мог получить из нее MemoryView.Структура, которую я хочу представить, похожа на эту:

struct ImageBuffer {
    void* bytes;
    int row_count;
    int bytes_per_row;
};

и я хочу предоставить автору сценария доступ к данным следующим образом:

img_buffer = img.get_buffer()
img_buffer[1::4] = 255 # Set every Red component to full intensity

К сожалению, существующая документация по API C для этих структур довольно скудна, местами противоречива, а в других совершенно неверна (документированные сигнатуры функций не совпадают с сигнатурами в заголовках и т. д.). Таким образом, у меня нет очень хорошей документации. идея о том, как лучше всего это раскрыть.Кроме того, я хотел бы избежать включения сторонних библиотек для достижения функциональности, которая должна быть частью основных библиотек, но мне кажется, что функциональность PyBuffer все еще довольно незрелая, и, возможно, что-то вроде NumPy было бы лучшим выбором.

Есть ли у кого-нибудь какие-нибудь советы по этому поводу?

Это было полезно?

Решение

Здесь описан набор методов, которые необходимо реализовать, чтобы ваш тип расширения поддерживал протокол буфера: http://docs.python.org/3.1/c-api/typeobj.html#buffer-object-structures

Я осознаю, что документация довольно приблизительна, поэтому лучший совет, который я могу дать, — это начать с существующей реализации буферного API типа C, например bytesobject.c или bytearrayobject.c в официальном исходном коде Python.

Однако обратите внимание, что протокол буфера не предоставляет доступ к нотациям высокого уровня, таким как та, которую вы процитировали: img_buffer[1::4] = 255 не будет работать с объектом MemoryView.

Редактировать: если быть более точным, представления памяти поддерживают некоторые виды назначения срезов, но не все из них.Кроме того, они недостаточно «умны», чтобы понять, что присвоение срезу значения 255 на самом деле означает, что вы хотите, чтобы значение байта повторялось.Пример:

>>> b = bytearray(b"abcd")
>>> m = memoryview(b)
>>> m[0:2] = b"xy"
>>> b
bytearray(b'xycd')
>>> m[0:2] = 255
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'int' does not support the buffer interface
>>> m[0:2] = b"x"
Traceback (most recent call last):
  File "", line 1, in 
ValueError: cannot modify size of memoryview object
>>> m[0::2] = b"xy"
Traceback (most recent call last):
  File "", line 1, in 
NotImplementedError
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top