Utilizzando ctypes pitone per ottenere tampone di galleggianti da libreria condivisa in stringa di pitone

StackOverflow https://stackoverflow.com/questions/704777

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.

È stato utile?

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: copie count byte dal src a dst. dst e src 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top