python - Return dynamic arrays by ref in Swig -


i'm using swig wrap code in c++ use in python.
have function array , return 2 dynamic arrays (the function them ref) after calculation on input array.
problem output arrays unspecified size, because size depends on input array.
function like:

void arraymanipulate(int* inarray, int inlen, int resolution, int* &outarray1, int &outlen1, int* &outarray2, int &outlen2) 

i used numpy.i cast input array numpy array.
if want use numpy return array argout not work, because assume size of output array known.

module.i:

%module minimal %{ #include "minimal.h" #include "numpy/arrayobject.h" %}  %include numpy.i %init %{ inport_array(); %} %apply (int* inarray1, int dim1) {(int* inarray, int inlen)} %apply (int* argout_array1, int dim1) {(int* &outarray1, int &outlen1), (int* &outarray2, int &outlen2) %include "minimal.h" 

if try compile this, folowing error:

file minimal_wrap.cxx: intellisense: value of type "int" not assigned entity od type "int *" file minimal_wrap.cxx: intellisense: value of type "int *" not assigned entity od type "int **" 

if remove "&" signs minimal.i , minimal.h (from function), compile excepct python give dimension of output arrays:

typeerror: arraymanipulate takes 4 arguments (2 given) 

i want use in python somthing like:

import minimal import numpy np arr1, arr2 = minimal.arraymanipulate(np.asarray([1,2,3]),100) 

how can make works?

here goes answer, uses double pointers rather *&. can make simple wrapper function support prototype

please note returned arrays allocated , typemap generates proxy ensures arrays deleted when deleted in python. managed

header file (test.h):

#pragma once  void fun(int* inarray, int inlen, int resolution,      int** outarray1, int* outlen1,      int** outarray2, int* outlen2); 

source file (test.cpp):

#include "test.h" #include <malloc.h>  void fun(int* inarray, int inlen, int resolution,       int** outarray1, int* outlen1,      int** outarray2, int* outlen2) {    int _outlen1 = resolution*inlen;   int _outlen2 = resolution*inlen;   int* _outarray1 = (int*)malloc(_outlen1*sizeof(int));   int* _outarray2 = (int*)malloc(_outlen2*sizeof(int));    (int = 0 ; < inlen ; i++) {     (int j = 0 ; j < resolution ; j++) {       _outarray1[i*resolution+j] = resolution*inarray[i];       _outarray2[i*resolution+j] = resolution*inarray[i];     }   }    // assign outputs   *outlen1 = _outlen1;   *outlen2 = _outlen2;   *outarray1 = _outarray1;   *outarray2 = _outarray2; } 

interface definition file (test.i)

%module example %{   #define swig_file_with_init   #include "test.h" %}  %include "numpy.i"  %init %{   import_array(); %}  %apply (int* in_array1, int dim1) {(int* inarray, int inlen)}  %apply (int** argoutviewm_array1, int* dim1) {(int** outarray1, int* outlen1)} %apply (int** argoutviewm_array1, int* dim1) {(int** outarray2, int* outlen2)}  %include "test.h" 

from within python

import numpy np import example = np.ones(27,dtype=np.int32) h = example.fun(a,2) # h contains 2 outputs 

to support e.g. size_t, search section in numpy.i

%numpy_typemaps(unsigned long long, npy_ulonglong, int) %numpy_typemaps(float             , npy_float    , int) %numpy_typemaps(double            , npy_double   , int) 

and add following

%numpy_typemaps(signed char       , npy_byte     , size_t) %numpy_typemaps(unsigned char     , npy_ubyte    , size_t) %numpy_typemaps(short             , npy_short    , size_t) %numpy_typemaps(unsigned short    , npy_ushort   , size_t) %numpy_typemaps(int               , npy_int      , size_t) %numpy_typemaps(unsigned int      , npy_uint     , size_t) %numpy_typemaps(long              , npy_long     , size_t) %numpy_typemaps(unsigned long     , npy_ulong    , size_t) %numpy_typemaps(long long         , npy_longlong , size_t) %numpy_typemaps(unsigned long long, npy_ulonglong, size_t) %numpy_typemaps(float             , npy_float    , size_t) %numpy_typemaps(double            , npy_double   , size_t) 

this add more typemaps support indexing using size_t rather int.


Comments

Popular posts from this blog

sequelize.js - Sequelize group by with association includes id -

android - Robolectric "INTERNET permission is required" -

java - Android raising EPERM (Operation not permitted) when attempting to send UDP packet after network connection -