swig help

Lyle Johnson lyle at users.sourceforge.net
Wed Apr 2 10:47:47 EST 2003


VanL wrote:

> I have a C file that has a function
> 
> void myfunc(int x, int y, int z, float *new_x, float *new_y, float *new_z);
> 
> I can create an interface to it fine, but the typemap stuff keeps 
> tripping me up -- I cannot seem to get it so that from python it looks like
> 
>  >>> result = myfunc(1,2,3)
>  >>> result
> (1.0, 2.0, 3.0)
> 
> Instead, it complains that it expects six arguments, the last three of 
> which need to be pointers to ints.
> 
> I have the following interface file:
> 
> %typemap(argout) float *OutValue {
>     PyObject *o, *o2, *o3;
>     o = PyFloat_FromFloat(*$1);
>     if ((!$result) || ($result == Py_None)) {
>         $result = o;
>     } else {
>         if (!PyTuple_Check($result)) {
>             PyObject *o2 = $result;
>             $result = PyTuple_New(1);
>             PyTuple_SetItem(target,0,o2);
>         }
>         o3 = PyTuple_New(1);
>         PyTuple_SetItem(o3,0,o);
>         o2 = $result;
>         $result = PySequence_Concat(o2,o3);
>         Py_DECREF(o2);
>         Py_DECREF(o3);
>     }
> }
> 
> %typemap(in,numinputs=0) double *OutValue(double temp) {
>     $1 = &temp;
> }
> 
> 
> void next(int x, int y, float z,
>           float *new_x, float *new_y, float *new_z);
> 
> 
> Could anyone tell me what I have wrong?

There are a number of problems ;)

Starting with the 'argout' typemap, the first problem is that there is 
no PyFloat_FromFloat() function, unless this is something new in Python 
2.3. The name of the function that converts from a floating-point value 
(either a float or a double) to a Python Float object is 
PyFloat_FromDouble().

The second problem is that you have a reference to 'target', which I 
think is a holdover from SWIG 1.1 days. That line of the typemap should 
instead read:

     PyTuple_SetItem($result, 0, o2);

Moving on to the 'in' typemap, the problem is that this typemap matches 
for doubles, whereas the first (the 'argout' typemap) matches for 
floats. The second typemap should presumably read:

     %typemap(in,numinputs=0) float *OutValue(float temp) {
         $1 = &temp;
     }

The final problem is that there's no way for SWIG to know that you want 
to apply those two typemaps to the "new_x", "new_y" and "new_z" 
arguments in the "next()" function declaration. Try adding these lines 
after the %typemap definitions, but before the declaration of next():

     %apply float *OutValue { float *new_x, float *new_y, float *new_z };

and then re-run SWIG, rebuild your extension and try again.

Now, having said all that, this is a pretty common case and is already 
handled by SWIG's built-in typemaps library. You could replace all of 
the above with:

     %include typemaps.i

     %apply float *OUTPUT { float *new_x, float *new_y, float *new_z };

     void next(int x, int y, float z,
               float *new_x, float *new_y, float *new_z);

and get the same result!

Hope this helps,

Lyle





More information about the Python-list mailing list