2015-05-15 6 views
2

Я использую Swig для интерфейса python с кодом C.Swig и многомерные массивы

Я хочу, чтобы вызвать функцию C, которая принимает для аргумента структуры, содержащей в Int ** вар:

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

void myCFunction(myStruct struct); 

Я борюсь с многомерными массивами.

Мой код выглядит следующим образом:

В файле интерфейса, я использую CARRAY так:

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

В питона, у меня есть:

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 **' 

Я сомневался в том, что linge% array_class (intArray, intArrayArray) Я попытался использовать typedef для int * для создания моего массива следующим образом: % array_class (myTypeDef, intArrayArray); Но, похоже, это не сработало.

Вы знаете, как обрабатывать многомерные массивы в Swig?

Благодарим за помощь.

+0

'INT ** my2Darray' фактически описывает ни 2D массив, ни указатель на один , Это указатель на массив «int *» и, возможно, на 1D таких. Хотя массивы и указатели тесно связаны в C, они вовсе не одно и то же. У меня нет рекомендации о том, как справиться с этим в Swig, но лучше всего начинать с разумного понимания ваших данных C. –

ответ

2

Считаете ли вы использование numpy? Я использовал numpy с моим SWIG-завернутым проектом C++ для 1D, 2D и 3D массивов двойных и std :: сложных элементов с большим успехом.

Вам понадобится get numpy.i и установите numpy в вашей среде python.

Вот пример того, как вы бы структурировать:

.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) 
0

Это, как я справилась с 2d массивов. Трюк, который я использовал, заключался в том, чтобы написать некоторый встроенный код для обработки создания и мутации массива. Как только это будет сделано, я смогу использовать эти функции для выполнения моих ставок.

Ниже приведен пример кода.

ddarray.я

%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) 
Смежные вопросы