Pergunta

EDIT: Após a re-ler a minha pergunta original percebi muito rapidamente que foi muito mal formulada, ambíguo, e muito confuso para nunca obter uma resposta decente. Isso é o que eu ganho por correndo para fora uma pergunta no final do meu horário de almoço. Esperemos que este será mais claro:

Eu estou tentando expor uma estrutura C simples para Python (3.x) como um PyBuffer para que eu possa recuperar um MemoryView dele. A estrutura eu quero expor é semelhante a este:

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

e é meu desejo para permitir que o roteirista para acessar os dados da seguinte forma:

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

Infelizmente a documentação existente sobre a API C para estas estruturas é bastante escassa, auto contraditória em alguns lugares, e outright errado em outros (assinaturas de função documentados não coincidem com aqueles nos cabeçalhos, etc.) como tal não tenho uma idéia muito boa sobre a melhor forma de expor isso. Além disso, eu gostaria de evitar incluindo libs de terceiros para alcançar a funcionalidade que deve ser parte das libs do núcleo, mas parece-me que a funcionalidade PyBuffer ainda é bastante imaturo, e talvez algo como NumPy seria uma escolha melhor.

Alguém tem algum conselho sobre isso?

Foi útil?

Solução

O conjunto de métodos para implementar de modo a que o seu tipo de extensão suporta o protocolo buffer é descrito aqui: http://docs.python.org/3.1/c-api/typeobj.html#buffer-object-structures

Eu reconheço que a documentação é muito difícil, então o melhor conselho que posso dar é para começar a partir de uma implementação existente da API tampão por um tipo C, por exemplo bytesobject.c ou bytearrayobject.c no código oficial fonte Python .

No entanto, note que o protocolo tampão não dá acesso a notações de alto nível, como o que você citou:. img_buffer[1::4] = 255 não vai funcionar em um objeto memoryview

Editar: para ser mais preciso, memoryviews suportar alguns tipos de atribuição fatia, mas não todos eles. Além disso, eles não são "inteligentes" o suficiente para entender que a atribuição de 255 para uma fatia na verdade significa que você deseja que o valor de byte a ser repetido. Exemplo:

>>> 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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top