如何使用Cython从c函数返回的2D数组?

时间:2018-03-28 09:49:46

标签: cython

我已成功使用Cython将numpy数组发送到c函数。每当我在c中有一个函数int *并且我在python中有一些变量时,将其称为arr,即1D numpy数组,我只需用&arr[0]调用该函数即可。

现在我有兴趣接收用c函数创建的2D数组。我怎样才能做到这一点?以下是我的尝试。

// this is the c code that returns a 2D array
int **make_array() {
  int nrows = 3;
  int ncols = 5;

  int **ret = malloc(nrows * sizeof(int *));
  ret[0] = calloc(nrows * ncols, sizeof(int));
  for (int i = 1; i < nrows; i++) {
    ret[i] = ret[0] + i * ncols;
  }

  int count = 0;
  for (int i = 0; i < nrows; i++)
    for (int j = 0; j < ncols; j++)
      ret[i][j] = ++count;

  return ret;
}

python代码

# python code that receives the 2D array
def foo():
    cdef int nRows = 3
    cdef int nCols = 5
    cdef int[:,::1] ret = np.zeros((nRows, nCols), dtype=np.int32)
    ret = make_array()

这给了我函数最后一行的以下错误:

Cannot convert 'int **' to memoryviewslice

如果我没有创建一个内存视图,而是在调用点创建一些变量来接收输出,那么对变量的赋值将正常工作。问题是我仍然无法弄清楚如何使用返回的值。例如,我不能这样做:

# python code that receives the 2D array
def foo():
    cdef int nRows = 3
    cdef int nCols = 5
    ret = make_array() # works
    print(ret) # fails

它抱怨同样的错误:

Cannot convert 'int **' to Python object

如何使用c函数返回int **

1 个答案:

答案 0 :(得分:1)

由于python无法转换C程序中的指针,我宁愿建议您在C代码中使用struct,然后按下面的值返回struct: -

struct TDArray {
    int arr[3][3];
};

struct TDArray make_array() {
    struct TDArray numbers = {
        {
            {0, 1, 2},
            {3, 4, 5},
            {6, 7, 8}
        }
    };//I am hard coding it you just need utilize this approach in your code
            /* Something like
            struct TDArray numbers;
            numbers.arr[0][0]=0;
           */

    return numbers;
}

希望这会对你有所帮助。