Utilizzando ctypes pitone per ottenere tampone di galleggianti da libreria condivisa in stringa di pitone
-
22-08-2019 - |
Domanda
Sto cercando di utilizzare ctypes python di utilizzare queste due funzioni C da una libreria condivisa:
bool decompress_rgb(unsigned char *data, long dataLen, int scale)
float* getRgbBuffer()
La prima funzione sta lavorando bene. Posso dire mettendo un po 'di codice di debug nella libreria condivisa e controllando l'ingresso.
Il problema è ottenere i dati fuori. Il buffer RGB è un puntatore ad un galleggiante (ovviamente) e questo puntatore rimane costante durante la vita dell'applicazione. Perciò ogni volta che voglio per decomprimere un'immagine, io chiamo decompress_rgb
e quindi bisogno di vedere ciò che è nella posizione puntata da getRgbBuffer
. So che la dimensione del buffer è (720 * 288 * sizeof (float)) quindi credo che questo deve entrare in gioco da qualche parte.
Non c'è nessun tipo c_float_p
così ho pensato di provare questo:
getRgbBuffer.restype = c_char_p
Poi faccio:
ptr = getRgbBuffer()
print "ptr is ", ptr
, che emette solo:
ptr = 3078746120
Sto indovinando che è l'indirizzo effettivo piuttosto che il contenuto, ma anche se ero dereferenziazione con successo il puntatore e ottenere i contenuti, sarebbe solo il primo carattere.
Come posso ottenere il contenuto del l'intero buffer in una stringa Python?
Modifica Ho dovuto cambiare:
getRgbBuffer.restype = c_char_p
a
getRgbBuffer.restype = c_void_p
ma poi la risposta di BastardSaint lavorato.
Soluzione
Non pienamente provato, ma penso che sia qualcosa seguendo questa linea:
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 è la funzione ctypes.memmove()
. Dal ctypes documentazione :
memmove(dst, src, count)
Uguale la funzione di libreria C standard di memmove: copiecount
byte dalsrc
adst
.dst
esrc
devono essere numeri interi o ctypes istanze che possono essere convertiti in puntatori.
Dopo che il pezzo di codice sopra è gestito, rgb_buffer.value
restituirà il contenuto fino alla prima '\0'
. Per ottenere tutti i byte come una stringa Python, è possibile tagliare il tutto:. buffer_contents = rgb_buffer[:]
Altri suggerimenti
E 'stato un po' che ho usato ctypes e non ho qualcosa che restituisce un "doppio *" abbastanza utile per testare il tutto, ma se volete un c_float_p:
c_float_p = ctypes.POINTER(ctypes.c_float)
La risposta di Reading BastardSaint, si vuole solo i dati grezzi, ma non ero sicuro se si sta facendo che come una soluzione per non avere un c_float_p.