Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python/SWIG: Output an array

I am trying to output an array of values from a C function wrapped using SWIG for Python. The way I am trying to do is using the following typemap.

Pseudo code:

int oldmain() {
float *output = {0,1};
return output;
}

Typemap:

%typemap(out) float* { 
   int i; 
  $result = PyList_New($1_dim0); 
   for (i = 0; i < $1_dim0; i++) { 
 PyObject *o = PyFloat_FromDouble((double) $1[i]); 
 PyList_SetItem($result,i,o); 
 } 
} 

My code compiles well, but it hangs when I run access this function (with no more ways to debug it).

Any suggestions on where I am going wrong?

Thanks.

like image 355
SEU Avatar asked Jul 26 '12 22:07

SEU


1 Answers

The easiest way to allow the length to vary is to add another output parameter that tells you the size of the array too:

%module test

%include <stdint.i>

%typemap(in,numinputs=0,noblock=1) size_t *len  {
  size_t templen;
  $1 = &templen;
}

%typemap(out) float* oldmain {
  int i;
  $result = PyList_New(templen);
  for (i = 0; i < templen; i++) {
    PyObject *o = PyFloat_FromDouble((double)$1[i]);
    PyList_SetItem($result,i,o);
  }
}

%inline %{
float *oldmain(size_t *len) {
  static float output[] = {0.f, 1.f, 2, 3, 4};
  *len = sizeof output/sizeof *output;
  return output;
}
%}

This is modified from this answer to add size_t *len which can be used to return the length of the array at run time. The typemap completely hides that output from the Python wrapper though and instead uses it in the %typemap(out) instead of a fixed size to control the length of the returned list.

like image 94
Flexo Avatar answered Sep 22 '22 16:09

Flexo