访问变量的问题,该变量在python中使用ctypes转换为指向int数组的指针

时间:2010-08-19 15:14:17

标签: python pointers casting multidimensional-array ctypes

我有一个使用变量data的C代码,这是一个用可变大小的malloc创建的大型2d数组。现在我必须编写一个接口,以便可以从Python中调用C函数。我使用ctypes。

C代码:

FOO* pytrain(float **data){
    FOO *foo = foo_autoTrain((float (*)[])data);
    return foo;
}

FOO *foo_autoTrain(float data[nrows][ncols]) {...}

Python代码:

autofoo=cdll.LoadLibrary("./libfoo.so")
... data gets filled ...
foo = autofoo.pytrain(pointer(pointer(p_data)))

我的问题是,当我尝试访问foo_autoTrain中的data时,我只会获得0.0或其他随机值以及稍后的段错误。那么我怎样才能在Python中将float (*)[])data传递给foo_autoTrain?

如果我描述的问题的某些部分还不够充分,请不要犹豫。

1 个答案:

答案 0 :(得分:0)

在我看来,这个问题是对多维数组如何在C中工作的误解。像a[r][c]这样的表达式可能意味着两种情况之一,具体取决于a的类型。如果a的类型是float **,那么表达式将意味着一个双指针偏移解除引用,如果长时间做完就是这样的:

float *row = a[r]; // First dereference yields a pointer to the row array
return row[c]      // Second dereference yields the value

如果a的类型是float (*)[ncols],则表达式只是将连续的一维内存区域整形为多维数组的简写:

float *flat = (float *)a;
return flat[(r * ncols) + c]; // Same as a[r][c]

因此,在您的C代码中,pytrain()的参数类型应为float *float (*)[ncols],您的Python代码应如下所示(假设您正在使用数组数据的NumPy:

c_float_p = ctypes.POINTER(ctypes.c_float)
autofoo.pytrain.argtypes = [c_float_p]
data = numpy.array([[0.1, 0.1], [0.2, 0.2], [0.3, 0.3]], dtype=numpy.float32)
data_p = data.ctypes.data_as(c_float_p)
autofoo.pytrain(data_p)

如果您实际上在使用NumPy,请查看ctypes page of the SciPy wiki