Я заинтересован в передаче двоичных данных между python, numpy и cython, используя буферный протокол. Глядя на PEP 3118 , кажется, что есть некоторые дополнения к синтаксису struct string, которые добавляют поддержку полезных функций, таких как именованные поля и вложенные структуры.
Однако, похоже, что поддержка всего диапазона синтаксиса буфера ограничена во всех этих трех местах. Например, скажем, у меня есть следующая структура cython:
ctypedef packed struct ImageComp:
uint32_t width
uint32_t height
uint8_t *pixels
#Here is the appropriate struct format string representation
IMAGE_FORMAT = b'T{L:width:L:height:&B:pixels:}'
Попытка извлечь строку байтов, соответствующую PEP-3118, следующим образом
cdef void *image_temp = malloc(sizeof(ImageComp))
IMAGE_SIZE = sizeof(ImageComp)
IMAGE_FORMAT = (<ImageComp[:1]>image_temp)._format
IMAGE_DTYPE = np.asarray(<ImageComp[:1]>image_temp).dtype
free(image_temp)
Сбой с этим сообщением об ошибке:
Invalid base type for memoryview slice: ImageComp
поскольку типизированные представления памяти не могут быть созданы, если они содержат указатели.
Аналогичным образом, создание view.array
с использованием моей пользовательской строки или с помощью функции calcsize
модуля python struct
даст предупреждение, подобное struct.error: bad char in struct format
.
Я могу вручную создать и заполнить Py_buffer
объект, как описано здесь , но попытка преобразовать его в массив с помощью np.asarray
приводит к ValueError: 'T{L:width:L:height:&B:pixels:}' is not a valid PEP 3118 buffer format string
.
Имея все это в виду, у меня есть следующие вопросы:
- Есть ли какой-либо модуль в стандартной библиотеке Python, который использует преимущества полной спецификации
PEP 3118
?
- Этот синтаксис формата структуры формально определен где-либо (то есть с помощью грамматики PEG)?
- Есть ли способ заставить cython или numpy автоматически генерировать правильную строку формата, если она содержит указатели?