Создание PyBuffer из структуры C - PullRequest
1 голос
/ 10 ноября 2009

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

Я пытаюсь представить простую структуру 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 Ответ

1 голос
/ 27 декабря 2009

Набор методов для реализации, чтобы ваш тип расширения поддерживал буферный протокол, описан здесь: 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 не будет работать с объектом вида памяти.

Редактировать: Точнее, просмотры памяти поддерживают некоторые виды назначения срезов, но не все. Кроме того, они недостаточно умны, чтобы понять, что присвоение 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...