Arnaud
Arnaud

Reputation: 223

Swig mapping from C++ function to python function specifying an additionnal OUTPUT parameter

I have a C++ function foo() returning the address of an internally created object with an integer used to provide an error code. In case of error, the returned address is null. I would like to map this function in python with SWIG. As python allows for a function to return several output parameters, I would like the mapped function to be called like this :

a,error = foo() 

I expect a to be None in case of a problem detected in foo() and error to be the error code.

Swig seems to allow this with the typemap specifications :

%include "typemaps.i"
%apply int * OUTPUT  {int * error}

in my example below

But it appears that foo return only one parameter in case the returned adress is null while it is OK when the object has been correctly allocated.

I added an additional parameter to switch between the two cases.

Here is my .i file :

%module TestSwig
%{
#include "truc.h"
%}
%include "typemaps.i"
%apply int * OUTPUT  {int * error}
%newobject foo;
%include "truc.h"

my .h file :

#ifndef TESTSWIG_TRUC_H
#define TESTSWIG_TRUC_H


class A {
public :
    int a = 5;
};

A* foo(int isnull, int * error);

#endif //TESTSWIG_TRUC_H

and .cpp file

#include "truc.h"

A* foo(int isnull, int * error) {
    if (isnull) {
        *error=1;
        return nullptr;
    }
    else {
        *error=0;
        return new A;
    }
}

and what I get when calling the mapped function from python3

>>> a,error = foo(0)
>>> print(a.a)
5
>>> print(error)
0
>>> a,error = foo(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot unpack non-iterable int object


Do you have an idea of how I can fix this. I guess, it is possible through typemap overwriting, but it's beyond my skills.

Upvotes: 0

Views: 12

Answers (0)

Related Questions