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
Post a Comment