2010-09-01 36 views
5

我使用ctypes来访问一个读取python中的C函数的文件。由于读取的数据非常庞大,尺寸未知,我在C中使用了**float使用ctypes访问一个变量数组的内容

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

功能mallocs一个二维数组,称为data,适当大小的,这里nm,并复制的值,以引用的那些。请参见下面的代码片段:

*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)) 

后来,我尝试使用contentsp_data进入电影,但我只得到一个浮点值。

p_data.contents 
c_float(-1.0) 

我的问题是:如何在python访问data

你推荐什么?请不要犹豫,指出我是否留下了不清楚的东西!

+0

+1对于ctypes,最好的python库 – amwinter 2010-09-01 18:36:55

回答

3

可能更简单的做在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; 
} 

,然后在蟒蛇:

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,因为它更清楚发生了什么事情。

+1

你也可以用ctypes解析二进制文件。我发现使用struct模块更容易一些。 – Mark 2010-09-02 15:33:07

+0

嗨Amwinter,你的回答已经让我更了解,但我还有两个问题。 1.我读了'15.16.1.7。从http://docs.python.org/library/ctypes.html指定所需的参数类型,我不明白为什么需要'argtypes'。我尝试了我的示例,但没有使用它,它也起作用。 2.我在'tags'中提到过它,但在实际的问题中忘了这么做。当数据不止一个维度时,这将如何工作?我尝试了'print p_data [0] [0]',但是我得到了一个TypeError:'float'对象是不可解析的。 – Framester 2010-09-03 09:59:32

+0

嗨@amwinter,我可以看到你在Python中是非常实验的,你可以帮助我[this](http://stackoverflow.com/questions/33377764/error-using-callback-in-python)吗? – 2015-10-27 23:51:33