Usando ctypes pitón para obtener búfer de flotadores de la biblioteca compartida en la cadena de Python
-
22-08-2019 - |
Pregunta
Estoy tratando de utilizar ctypes pitón de utilizar estas dos funciones C a partir de una biblioteca compartida:
bool decompress_rgb(unsigned char *data, long dataLen, int scale)
float* getRgbBuffer()
La primera función está trabajando muy bien. Puedo decir por poner algo de código de depuración en la biblioteca compartida y el control de la entrada.
El problema es conseguir los datos a cabo. El buffer RGB es un puntero a un flotador (obviamente) y este puntero se mantiene constante durante la vida de la aplicación. Por lo tanto, siempre que lo desee para descomprimir una imagen, que llamo decompress_rgb
y luego necesito ver lo que está en la ubicación a la que apunta getRgbBuffer
. Yo sé que el tamaño del búfer es (720 * 288 * sizeof (float)) así que supongo que esto tiene que entrar en juego en alguna parte.
No hay ningún tipo c_float_p
así que pensé que iba a tratar esto:
getRgbBuffer.restype = c_char_p
A continuación hago:
ptr = getRgbBuffer()
print "ptr is ", ptr
que acaba de salidas:
ptr = 3078746120
supongo que esa es la dirección real en lugar del contenido, pero incluso si me eliminación de referencias con éxito el puntero y obtener el contenido, que sólo sería el primer carácter.
¿Cómo puedo obtener el contenido de toda la memoria intermedia en una cadena pitón?
Editar Tuvimos que cambiar:
getRgbBuffer.restype = c_char_p
a
getRgbBuffer.restype = c_void_p
pero luego la respuesta de BastardSaint trabajaban.
Solución
No es completamente probado, pero creo que es algo a lo largo de esta línea:
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 es la función ctypes.memmove()
. Desde el ctypes documentación :
memmove(dst, src, count)
Igual que la función de biblioteca C estándar memmove: copiascount
bytes desdesrc
adst
.dst
ysrc
deben ser números enteros o ctypes casos que se pueden convertir a los punteros.
Después de que se ejecute el código anterior, rgb_buffer.value
volverá el contenido hasta la primera '\0'
. Para obtener todos los bytes como una cadena Python, puede cortar todo el asunto:. buffer_contents = rgb_buffer[:]
Otros consejos
Ha sido un tiempo desde que se utiliza ctypes y no tener algo que devuelve un "doble *" suficientemente práctico para probar esto, pero si quieres un c_float_p:
c_float_p = ctypes.POINTER(ctypes.c_float)
La respuesta de lectura BastardSaint, lo que desea los datos en bruto, pero no estaba seguro de si está haciendo eso como una solución para no tener un c_float_p.