我有一个使用变量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?
如果我描述的问题的某些部分还不够充分,请不要犹豫。
答案 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。