Доступ к содержимому массива переменных с помощью ctypes - PullRequest
5 голосов
/ 01 сентября 2010

Я использую ctypes для доступа к функции чтения файла C в python. Поскольку прочитанные данные огромны и неизвестны по размеру, я использую **float на Си.

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

Функции mallocs двухмерный массив, называемый data, соответствующего размера, здесь n и m, и копирует значения в указанные. Смотрите следующий фрагмент:

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

Я получаю доступ к этой функции с помощью следующего кода 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))

После этого я пытаюсь получить доступ к p_data, используя contents, но получаю только одно значение с плавающей точкой.

p_data.contents
c_float(-1.0)

Мой вопрос: как мне получить доступ к data в python?

Что вы порекомендовали? Пожалуйста, не стесняйтесь указывать, если я оставил что-то неясное!

1 Ответ

3 голосов
/ 01 сентября 2010

может быть проще сделать все это в python с библиотекой struct.но если вы проданы на ctypes (и я не виню вас, это круто):

#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;
}

, а затем на 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]

хитрость в том, что заглавныеPOINTER делает тип и строчные буквы pointer делает указатель на существующее хранилище.вы можете использовать byref вместо pointer, они утверждают, что это быстрее.Мне нравится pointer лучше, потому что понятно, что происходит.

...