[Numpy-discussion] [EXTERNAL] Re: SWIG Numpy and C++ extensions

David Froger david.froger at gmail.com
Wed Aug 1 16:45:49 EDT 2012


On Tue, 31 Jul 2012 14:48:24 -0600, "Bill Spotz" <wfspotz at sandia.gov> wrote:
> Use %inline %{ ... %} around your function.  SWIG will add your function directly to the wrapper file as well as add a wrapper function for calling it from python.
> 
> On Jul 31, 2012, at 2:04 PM, David Froger wrote:
> 
> >> 2-that's ok if your C++ deals with arrays but what if I actually want to receive the Numpy object so that I can manipulate it directly (or if for example the array isn't contiguous in memory)
> >> 
> >> An"dummy"example of foo function I'd like to wrap:
> >> 
> >>     void FOO::fooNumpy(PyArrayObject *nparray) {
> >> 
> >>      int j;
> >>      for(j=0;j<nparray->nd;j++) {
> >> printf("Ok array dim %i has length: %i\n",j,nparray->dimensions[j]);
> >>      }
> >>    }
> 
> ** Bill Spotz                                              **
> ** Sandia National Laboratories  Voice: (505)845-0170      **
> ** P.O. Box 5800                 Fax:   (505)284-0154      **
> ** Albuquerque, NM 87185-0370    Email: wfspotz at sandia.gov **

I think that the problem will be that Swig does not know the declaration of
PyArrayObject, so a SWIGTYPE_p_PyArrayObject type will be generated for the
Swig run-time type checker, and numpy array will not be accepted as input.
On the other hand, SWIGTYPE_p_PyArrayObject is usefull  because if a C function
foo return a PyArrayObject * and a function bar take a PyArrayObject * as argument,
one could do with the wrapper generated by Swig:
array = foo() # array is unusable in Python
bar(array)    # but it is accepted by bar

A solution could be to collect informations about PyArrayObject with
'%import "ndarraytypes.h"', but it may be hard to make Swig parse it
without errors.

Another solution (the test works) could be to define the "in" typemap:

%module demo

%{
#define SWIG_FILE_WITH_INIT
%}

%include "numpy.i"

%init %{
    import_array();
%}

%typemap(in,fragment="NumPy_Macros") (PyArrayObject *nparray) {
  if (! is_array($input)) {
      PyErr_Format(PyExc_TypeError, "An array is required.");
      SWIG_fail;
  }
  $1 = (PyArrayObject*) $input;
}

%inline
%{  
    void foo(PyArrayObject *nparray) {
     int j;
     for(j = 0; j < nparray->nd ; j++) {
       printf("Ok array dim %i has length: %i\n",j,nparray->dimensions[j]);
     }
   }
%}



More information about the NumPy-Discussion mailing list