通过一些黑客攻击,我使用python c-types在Python和C之间来回传递数据。这看起来有点乱,所以我希望有更多经验的人可以告诉我,如果我做错了什么,或者说这比你需要的更难。
Python代码:
from ctypes import cdll, POINTER, byref, c_double
lib = cdll.LoadLibrary('./test.so')
def alloc_arrays(length, python_list):
# Create array of float*
data = ((POINTER(c_double)) * length)()
out_data = ((POINTER(c_double)) * length)()
for i in xrange(length):
# Create arrays of float
data[i] = (c_double * 3)()
out_data[i] = (c_double * 3)()
# Set Values
for j in xrange(3):
data[i][j] = python_list[i][j]
out_data[i][j] = 0.0
return data, out_data
if __name__ == "__main__":
a = [[1.0, 11.0, 21.0],
[2.0, 12.0, 22.0],
[3.0, 13.0, 23.0],
[4.0, 14.0, 24.0],
[5.0, 15.0, 25.0],
[6.0, 16.0, 26.0],
[7.0, 17.0, 27.0]]
in_data, out_data = alloc_arrays(len(a), a)
out_len = lib.smain(byref(in_data), len(a), out_data)
print "out_len", out_len
clean_out = [None, None, None]
clean_out = [clean_out[:] for i in xrange(out_len)]
for i in xrange(out_len):
for j in xrange(3):
clean_out[i][j] = out_data[i][j]
print "Out:", clean_out
C代码(test.c):
int smain(double* in_points[3], int in_len, double* out_points[3]){
int i;
int j;
printf("%s", "\n");
for(i = 0; i < in_len; i++){
for(j = 0; j < 3; j++){
printf("%g, ", *in_points[i][j]);
}
printf("%s", "\n");
}
printf("%s", "\n");
//*out_points = malloc(len*sizeof(float[3]));
int out_len = in_len-2; //Randomly chosen shorter length
for(i = 0; i < out_len; i++){
for(j = 0; j < 3; j++){
//Random function just to see I can do this
*out_points[i][j] = i*j;
}
}
return out_len;
}
构建我使用:
gcc -c -fPIC test.c
gcc -shared -o test.so test.o
我想知道的主要事情是,是否有更好的方法来创建空的2D向量以传递到C,并且如果有更好的方法将变量转换为/从ctypes到python类型。我不喜欢alloc_arrays函数必须进行转换,我不喜欢让我的for循环读取c_types 2D列表(只是意识到我做得有点乱)。
编辑:只是想明确这段代码按预期工作,我认为必须有一些方法来改进它。
答案 0 :(得分:0)
这不是关于您的确切代码和ctypes的答案,但我想贡献...
我最近刚进入cython。我甚至不是中级的,但它似乎对编写扩展更加友好,并且有很多关于使用numpy数组的例子。
到目前为止,我发现cython非常棒,因为它可以让你保持类似python的语法,并且可以自由地混合python。在帮助将代码转换为封装器中的C方面,它为您处理了相当多的繁重工作。并且生成的.so
中没有中间依赖项。只是一个纯粹的扩展。
如果您在python代码中使用numpy,那么将它们传递到您的扩展中将毫不费力,因为它不需要进行任何转换。 numpy本身在python方面已经是一个很大的加速,但是做额外的自定义东西会让你只是将numpy指针传递到cython扩展端。