SWIG typemap to pass complex arrays into C++

Lyle Johnson lyle at users.sourceforge.net
Fri May 31 11:03:15 EDT 2002


> The function getel is illustrative only - not part of a real problem.
> 
> I have written a SWIG typemap to allow complex number arrays to be
> passed:
> 
> %typemap(python,in) dcomplex *
> {
>   if (!PyList_Check($input))
>         {
>           PyErr_SetString(PyExc_TypeError, "expected a list");
>           return NULL;
>         };
> 
>   int arrsize = PyList_Size($input);
> 
>   $1 = (dcomplex *)malloc(sizeof(dcomplex)*(arrsize+1));
>   for (int i=0; i<arrsize; i++)
>   {
>      PyObject *item = PyList_GetItem($input, i);
>      if (PyComplex_Check(item))
>            $1[i] = dcomplex(PyComplex_RealAsDouble(item),
>                                 PyComplex_ImagAsDouble(item));
>      else
>      {
>        free ((dcomplex *) $input);
>        PyErr_SetString(PyExc_TypeError, "expected complex numbers in
> list");
>        return NULL;
>      };
> 
>   }
> 
> }
> 
> %typemap (python,freearg) dcomplex *
> {
>    free ((dcomplex *) $input);
> };
> 
> SWIG (1.3.11u) runs ok. BCC5.5 compiles the wrapper file ok. But when
> I try to use the function getel from Python 2.2.1 I get the error
> message:
> 
> TypeError: Type error. Expected _p_dcomplex
> 
> I hand-coded my own wrapper and that worked, but can't make the
> typemap work. Any suggestions?

Do the typemap definitions appear before the declaration of getel() in 
your SWIG interface file? It wasn't clear from the code you showed, but 
the correct sequence in your SWIG interface file should be:

     // Make sure SWIG knows about this typedef
     typedef complex<double> dcomplex;

     // Typemaps for this typedef must appear before any
     // other declarations (such as getel) that depend on them
     %typemap(in) dcomplex * {
         ...
     }

     %typemap(freearg) dcomplex * {
         delete [] $1;
     }

     // Finally, the declaration of the function to be wrapped
     double getel (dcomplex *A, int i);

As an aside (not directly related to this problem) you should use 
operator new and delete in your typemaps to allocate and deallocate the 
arrays of complex<double>, i.e.

     $1 = new dcomplex[arrsize];

and

     delete [] $1;

since these are C++ objects and not simple C types.

Hope this helps,

Lyle




More information about the Python-list mailing list