2010-09-01 20 views
5

Utilizo ctypes para acceder a un archivo que lee la función C en python. Como los datos de lectura son enormes y de un tamaño desconocido, utilizo **float en C.Accediendo al contenido de una matriz variable con ctypes

int read_file(const char *file,int *n_,int *m_,float **data_) {...}

Las funciones mallocs una matriz 2D, llamados data, del tamaño adecuado, aquí n y m, y copia los valores a los que se hace referencia queridos. Veo siguiente fragmento:

*data_ = data; 
*n_ = n; 
*m_ = m; 

puedo acceder a esta función con el siguiente código Python:

p_data=POINTER(c_float) 
n=c_int(0) 
m=c_int(0) 
filename='datasets/usps' 
read_file(filename,byref(n),byref(m),byref(p_data)) 

Después trato de acces p_data usando contents, pero me da un solo valor flotante.

p_data.contents 
c_float(-1.0) 

Mi pregunta es: ¿Cómo puedo acceder a data en Python?

¿Qué recomienda? Por favor, no dudes en señalar si dejé algo poco claro.

+0

+1 para ctypes, la mejor biblioteca de python – amwinter

Respuesta

3

puede ser más simple para hacer todo en python con la biblioteca struct. pero si lo que venden en ctypes (y no te culpo, que es muy bueno):

#include <malloc.h> 
void floatarr(int* n, float** f) 
{ 
    int i; 
    float* f2 = malloc(sizeof(float)*10); 
    n[0] = 10; 
    for (i=0;i<10;i++) 
    { f2[i] = (i+1)/2.0; } 
    f[0] = f2; 
} 

y luego en Python:

from ctypes import * 

fd = cdll.LoadLibrary('float.dll') 
fd.floatarr.argtypes = [POINTER(c_int),POINTER(POINTER(c_float))] 

fpp = POINTER(c_float)() 
ip = c_int(0) 
fd.floatarr(pointer(ip),pointer(fpp)) 
print ip 
print fpp[0] 
print fpp[1] 

el truco es que los capitales POINTER hace un tipo y minúsculas pointer hace un puntero al almacenamiento existente. puede usar byref en lugar de pointer, afirman que es más rápido. Me gusta pointer mejor porque está más claro lo que está sucediendo.

+1

También puede usar ctypes para analizar archivos binarios. Me resulta un poco más fácil trabajar con el módulo struct. – Mark

+0

Hola Amwinter, tu respuesta ya me hizo entender más, pero me quedan dos preguntas. 1. Leí '15.16.1.7. Especificando los tipos de argumento requeridos' de http://docs.python.org/library/ctypes.html y no entiendo por qué 'argtypes' es necesario. Probé mi ejemplo sin usarlo y funcionó también. 2. Lo mencioné en las 'etiquetas' pero olvidé hacerlo en las preguntas reales. ¿Cómo funcionaría esto cuando los datos tuvieran más de una dimensión? Intenté 'imprimir p_data [0] [0]' pero obtuve un objeto 'TypeError: 'float' unsubscriptable'. – Framester

+0

Hola @amwinter, puedo ver que estás muy experimentado en Python ¿me puedes ayudar con [esto] (http://stackoverflow.com/questions/33377764/error-using-callback-in-python), por favor? –

Cuestiones relacionadas