【问题标题】:Accessing the content of a variable array with ctypes使用 ctypes 访问变量数组的内容
【发布时间】:2011-04-06 22:16:23
【问题描述】:

我使用 ctypes 在 python 中访问读取 C 函数的文件。由于读取的数据巨大且大小未知,我在 C 中使用 **float

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

函数mallocs 一个二维数组,称为data,具有适当的大小,此处为nm,并将值复制到引用的数组。见以下sn-p:

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

之后我尝试使用contents 访问p_data,但我只得到一个浮点值。

p_data.contents
c_float(-1.0)

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

你有什么推荐的?如果我有不清楚的地方,请随时指出!

【问题讨论】:

  • +1 for ctypes,最好的python库

标签: python pointers multidimensional-array ctypes


【解决方案1】:

使用struct 库在python 中完成整个操作可能会更简单。但是,如果您在 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,因为它更清楚发生了什么。

【讨论】:

  • 你也可以使用ctypes来解析二进制文件。我发现使用 struct 模块更容易一些。
  • 您好 Amwinter,您的回答已经让我明白了更多,但我还有两个问题。 1. 我从docs.python.org/library/ctypes.html 中读到15.16.1.7. Specifying the required argument types,但我不明白为什么需要argtypes。我在没有使用它的情况下尝试了我的示例,并且效果也很好。 2. 我在tags 中提到过,但在实际问题中忘记了。当数据不止一维时,这将如何工作?我试过print p_data[0][0],但我得到了TypeError: 'float' object is unsubscriptable
  • 嗨 @amwinter,我可以看到你在 Python 方面很有经验,你能帮我this,好吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
相关资源
最近更新 更多