【问题标题】:Swig and multidimensional arraysSwig 和多维数组
【发布时间】:2015-07-27 09:12:02
【问题描述】:

我正在使用 Swig 将 python 与 C 代码接口。

我想调用一个以包含 int** var 的结构为参数的 C 函数:

typedef struct
{
    (...)
    int** my2Darray;
} myStruct;

void myCFunction( myStruct struct );

我正在努力处理多维数组。

我的代码如下所示:

在接口文件中,我使用的是这样的数组:

%include carrays.i
%array_class( int, intArray );
%array_class( intArray, intArrayArray );

在 python 中,我有:

myStruct = myModule.myStruct()
var = myModule.intArrayArray(28)

for j in range(28):
    var1 = myModule.intArray(28)

    for i in range(28):
        var1[i] = (...) filling var1 (...)

    var[j] = var1

myStruct.my2Darray = var

myCFonction( myStruct )

我在myStruct.my2Darray = var 行收到错误:

TypeError: in method 'maStruct_monTableau2D_set', argument 2 of type 'int **'

我怀疑%array_class( intArray, intArrayArray ) 这一行。 我尝试使用 int* 的 typedef 来创建我的数组,如下所示: %array_class( myTypeDef, intArrayArray ); 但这似乎不起作用。

你知道如何在 Swig 中处理多维数组吗?

感谢您的帮助。

【问题讨论】:

  • int** my2Darray 实际上既不描述二维数组,也不描述指向数组的指针。它是一个指向int * 的指针,并且可能指向这样的一维数组。尽管数组和指针在 C 中密切相关,但它们根本不是一回事。我没有关于如何在 Swig 中处理此问题的建议,但最好从对 C 数据的充分理解开始。

标签: python c arrays multidimensional-array swig


【解决方案1】:

这就是我处理二维数组的方式。我使用的技巧是编写一些内联代码来处理数组的创建和变异。完成后,我就可以使用这些功能进行竞标了。

下面是示例代码。

ddarray.i

%module ddarray
%inline %{
// Helper function to create a 2d array
int* *int_array(int rows, int cols) {
    int i;
    int **arr = (int **)malloc(rows * sizeof(int *));
    for (i=0; i<rows; i++)
        arr[i] = (int *)malloc(cols * sizeof(int)); 
    return arr;
 }

void *setitem(int **array, int row, int col, int value) {
    array[row][col] = value;
    }
%}

ddarray.c

int calculate(int **arr, int rows, int cols) {
    int i, j, sum = 0, product;
    for(i = 0; i < rows; i++) {
        product = 1;
        for(j = 0; j < cols; j++)
            product *= arr[i][j];
        sum += product;
    }
    return sum;
}

示例 Python 脚本

import ddarray

a = ddarray.int_array(2, 3)
for i in xrange(2):
    for j in xrange(3):
        ddarray.setitem(a, i, j, i + 1)

print ddarray.calculate(a, 2, 3)

【讨论】:

    【解决方案2】:

    您是否考虑过为此使用numpy?我已经在我的 SWIG 包装的 C++ 项目中使用 numpy 来处理双精度和 std::complex 元素的 1D、2D 和 3D 数组,并取得了很大的成功。

    您需要get numpy.i 并在您的 python 环境中安装 numpy。

    以下是您如何构建它的示例:

    .i 文件:

    // Numpy Related Includes:
    %{
    #define SWIG_FILE_WITH_INIT
    %}
    // numpy arrays
    %include "numpy.i"
    %init %{
    import_array(); // This is essential. We will get a crash in Python without it.
    %}
    // These names must exactly match the function declaration.
    %apply (int* INPLACE_ARRAY2, int DIM1, int DIM2) \
          {(int* npyArray2D, int npyLength1D, int npyLength2D)}
    
    %include "yourheader.h"
    
    %clear (int* npyArray2D, int npyLength1D, int npyLength2D);
    

    .h 文件:

    /// Get the data in a 2D Array.
    void arrayFunction(int* npyArray2D, int npyLength1D, int npyLength2D);
    

    .cpp 文件:

    void arrayFunction(int* npyArray2D, int npyLength1D, int npyLength2D)
    {
        for(int i = 0; i < npyLength1D; ++i)
        {
            for(int j = 0; j < npyLength2D; ++j)
            {
                int nIndexJ = i * npyLength2D + j;
                // operate on array
                npyArray2D[nIndexJ];
            }
        }
    }
    

    .py 文件:

    def makeArray(rows, cols):
        return numpy.array(numpy.zeros(shape=(rows, cols)), dtype=numpy.int)
    
    arr2D = makeArray(28, 28)
    myModule.arrayFunction(arr2D)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-07
      • 2011-05-06
      • 2012-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多