Usando ctypes Python para obter tampão de carros alegóricos da biblioteca compartilhada em cadeia de python
-
22-08-2019 - |
Pergunta
Eu estou tentando usar ctypes Python para usar estas funções dois C a partir de uma biblioteca compartilhada:
bool decompress_rgb(unsigned char *data, long dataLen, int scale)
float* getRgbBuffer()
fino A primeira função está funcionando. Eu posso dizer, colocando algum código de depuração na biblioteca compartilhada e verificando a entrada.
O problema é obter os dados fora. O tampão RGB é um ponteiro para uma bóia (obviamente) e esta constante estadias ponteiro durante a vida do pedido. Portanto, sempre que eu quero para descomprimir uma imagem, eu chamo decompress_rgb
e, em seguida, precisa ver o que está no local apontado pelo getRgbBuffer
. Eu sei que o tamanho do buffer é (720 * 288 * sizeof (float)) então eu acho que isso tem que entram em jogo em algum lugar.
Não há nenhum tipo c_float_p
então eu pensei que eu tente o seguinte:
getRgbBuffer.restype = c_char_p
Então eu faço:
ptr = getRgbBuffer()
print "ptr is ", ptr
que apenas saídas:
ptr = 3078746120
Eu estou supondo que é o endereço real e não o conteúdo, mas mesmo se eu estava dereferencing com sucesso o ponteiro e obter o conteúdo, que seria apenas o primeiro caractere.
Como posso obter o conteúdo de todo o buffer em uma seqüência de python?
Editar: teve que mudar:
getRgbBuffer.restype = c_char_p
para
getRgbBuffer.restype = c_void_p
mas, em seguida, a resposta de BastardSaint trabalhou.
Solução
Não totalmente testados, mas eu acho que é algo ao longo desta linha:
buffer_size = 720 * 288 * ctypes.sizeof(ctypes.c_float)
rgb_buffer = ctypes.create_string_buffer(buffer_size)
ctypes.memmove(rgb_buffer, getRgbBuffer(), buffer_size)
Key é a função ctypes.memmove()
. Do ctypes documentação :
memmove(dst, src, count)
Mesmo que a função de biblioteca C memmove padrão: cópiascount
bytes desrc
paradst
.dst
esrc
devem ser inteiros ou ctypes instâncias que podem ser convertidos em ponteiros.
Depois que o trecho acima é executado, rgb_buffer.value
irá retornar o conteúdo até o primeiro '\0'
. Para obter todos os bytes como uma string Python, você pode cortar a coisa toda:. buffer_contents = rgb_buffer[:]
Outras dicas
Tem sido um tempo desde que eu usei ctypes e eu não ter algo que retorna um "double *" bastante útil para testar isso, mas se você quiser um c_float_p:
c_float_p = ctypes.POINTER(ctypes.c_float)
A resposta de Leitura BastardSaint, você quer apenas os dados brutos, mas eu não tinha certeza se você está fazendo isso como uma solução para não ter um c_float_p.