Search code examples
pythonswigtypemaps

Returning arguments in SWIG/Python


According to Swig docs and the marvelous explanation at SWIG in typemap works, but argout does not by @Flexo, the argout typemap turns reference arguments into return values in Python.

I have a scenario, in which I pass a dict, which then is converted to an unordered_map in typemap(in), which then gets populated in the C++ lib. Stepping through the code, I can see the mapping changed after it returned from C++, so I wonder why there is not a possibility to just convert the unordered_map back in place in to the dict that was passed. Or is it possible by now and I'm just overlooking something?

Thanks!


Solution

  • I am a little confused as to what exactly you are asking, but my understanding is:

    • You have an "in" typemap to convert a Python dict to a C++ unordered_map for some function argument.
    • The function then modifies the unordered_map.
    • After completion of the function, you want the Python dict updated to the current unordered_map, and are somehow having trouble with this step.
    • Since you know how to convert a dict to an unordered_map, I assume you basically do know how to convert the unordered_map back to the dict using the Python C-API, but are somehow unsure into which SWIG typemap to put the code.

    So, under these assumptions, I'll try to help:

    • "the argout typemap turns reference arguments into return values in Python". Not really, although it is mostly used for this purpose. An "argout" typemap simply supplies code to deal with some function argument (internally referred to as $1) that is inserted into the wrapper code after the C++ function is called. Compare this with an "in" typemap that supplies code to convert the supplied Python argument $input to a C++ argument $1, which is obviously inserted into the wrapper code before the C++ function is called.

    • The original passed Python dict can be referred to in the "argout" typemap as $input, and the modified unordered_map as $1 (see the SWIG docs linked above).

    • Therefore, all you need to do is write an "argout" typemap for the same argument signature as the "in" typemap that you already have, and insert the code (using the Python C-API) to update the contents of the Python dict ($input) to reflect the contents of the unordered_map ($1).

    • Note that this is different from the classical use of "argout" typemaps, which would typically convert the $1 back to a new Python dict and append this to the Python return object, which you can refer to by $result.

    I hope this helps. If you are still stuck at some point, please edit your question to make clear at which point you are having trouble.