How to receive reference and pointer arguments in Python + SWIG?
Question: I have a C++ function in which two arguments are given as the following
example.

    
    
    void func(int& n, char** data)
    {
      *data = other_func1(); // returns a char array
      n = other_func2(); // returns the length of the array
    }
    

I can easily use this function in C or C++, but I do not know how I can call
it from a Python module generated with SWIG. I suppose that I will have to
write another C++ function which returns, for example, std::pair. But if
possible, I would like to know a workaround in the Python side. Could anyone
help?


Answer: For quite a lot of cases (e.g. `int *n`) it would be sufficient to write:

    
    
    %apply int *OUTPUT { int *n };
    

which uses some default typemaps that SWIG provides for output parameters.
(There is also INOUT and INPUT which are similar).

In this instance though we don't quite match any of the predefined cases, so
we need to do the same thing manually. That's basically two typemaps per
argument - an input typemap which creates something temporary for the actual
function call and uses that instead of some real input and an argout that
marshals the result back from the temporary to Python. In the case of Python
it makes sense to use a tuple for returning multiple arguments.

An example:

    
    
    %module test
    
    %typemap(in,numinputs=0) int& n (int temp) "$1 = &temp;"
    %typemap(in,numinputs=0) char **data (char *temp) "$1 = &temp;"
    
    %typemap(argout) char **data {
      %append_output(PyString_FromString(*$1));
    }
    
    %typemap(argout) int& n {
      %append_output(PyInt_FromLong(*$1));
    }
    
    %inline %{
      void foo(int& n, char **data) {
        static char str[] = "Hello world";
        *data = str;
        n = sizeof str;
      }
    %}
    

Points to note:

The temporary variables (`int temp`, `char *temp`) automatically get renamed
which stops the apparent name clash. `%append_output` is a SWIG macro that
expands to add something to the back of the `$result` tuple in Python. If your
function `foo` were dynamically allocated memory you'd need to handle that.
The freearg typemap is often useful if the in typemap needs to dynamically
allocate memory.

This was sufficient to allow me to compile and run it like:

    
    
    import test
    
    len,str = test.foo()
    
    print len
    print str
    

