Создание PyBuffer из структуры C
РЕДАКТИРОВАТЬ: Перечитав мой оригинальный вопрос, я очень быстро понял, что он был очень плохо сформулирован, неоднозначен и слишком запутан, чтобы когда-либо получить достойный ответ. Вот что я получаю за то, что спешу задать вопрос в конце моего обеденного перерыва. Надеюсь, это будет понятнее:
Я пытаюсь представить простую структуру 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
К сожалению, существующая документация по C API для этих структур довольно скудна, местами противоречива и совершенно неверна в других (документированные сигнатуры функций не совпадают с сигнатурами в заголовках и т. Д.) Идея о том, как лучше всего это разоблачить. Кроме того, я хотел бы избежать включения сторонних библиотек для достижения функциональности, которая должна быть частью основных библиотек, но мне кажется, что функциональность PyBuffer все еще довольно незрелая, и, возможно, что-то вроде NumPy будет лучшим выбором.
У кого-нибудь есть совет по этому поводу?
1 ответ
Набор методов для реализации, чтобы ваш тип расширения поддерживал буферный протокол, описан здесь: http://docs.python.org/3.1/c-api/typeobj.html
Я признаю, что документация довольно грубая, поэтому лучший совет, который я могу дать, - это начать с существующей реализации API буфера по типу C, например bytesobject.c или bytearrayobject.c в официальном исходном коде Python.
Тем не менее, обратите внимание, что буферный протокол не дает доступа к высокоуровневым нотациям, таким как та, которую вы цитировали: img_buffer[1::4] = 255
не будет работать с объектом памяти.
Редактировать: чтобы быть более точным, просмотры памяти поддерживают некоторые виды назначения срезов, но не все из них. Кроме того, они недостаточно умны, чтобы понять, что присвоение 255 срезу фактически означает, что вы хотите, чтобы значение байта повторялось. Пример:
>>> b = bytearray (b "abcd") >>> m = memoryview (б) >>> m[0:2] = b"xy" >>> б ByteArray(b'xycd') >>> m[0:2] = 255 Traceback (последний вызов был последним): Файл "", строка 1, в Ошибка типа: int не поддерживает интерфейс буфера >>> m[0:2] = b"x" Traceback (последний вызов был последним): Файл "", строка 1, в ValueError: невозможно изменить размер объекта вида памяти >>> m[0::2] = b"xy" Traceback (последний вызов был последним): Файл "", строка 1, в NotImplementedError