在Python和C之间传递2D可变长度数组的好方法?

在Python和C之间传递2D可变长度数组的好方法?,python,c,ctypes,Python,C,Ctypes,通过一些黑客攻击,我得到了使用PythonC-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

通过一些黑客攻击,我得到了使用PythonC-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):

我想知道的主要事情是,是否有更好的方法来创建空的2D向量以传递到C中,以及是否有更好的方法将变量强制转换为C类型或从C类型转换为python类型。我不喜欢alloc_arrays函数必须进行转换,我也不喜欢让for循环读取c_types 2D列表(只是意识到我做的也有点混乱)


编辑:我只是想澄清一下,这段代码的工作原理与预期相符,我只是认为必须有一些方法来改进它。

这并不是关于您的确切代码和C类型的答案,但我想对此做出贡献

我最近刚进入赛顿。我甚至还不是中级的,但是它对于编写扩展似乎更友好,而且有很多关于使用numpy数组的例子

到目前为止,我发现cython非常棒,因为它允许您保持类似python的语法,并且可以自由地混合python。它为您处理了大量繁重的工作,帮助您在包装器中将代码转换为C,这是在幕后完成的。而且生成的
中没有中间依赖项。因此
。只是一个纯粹的扩展


如果要在python代码中使用numpy,那么将它们传递到扩展中将很容易,因为它不必进行任何转换。numpy本身在python端已经是一个很大的加速,但是做额外的自定义工作将允许您将numpy指针传递到cython扩展端。

如果我尝试使用
gcc-std=c99-shared-o test.so-fPIC test.c来编译您的c代码,我会得到
一元'*'的无效类型参数(有'double')
printf(“%g,”,*in_点[i][j])的错误消息
*输出点[i][j]=i*j原因可能是什么?
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