How does SWIG wrap a map in Python?

前端 未结 1 409
暗喜
暗喜 2020-12-17 18:31

I\'m using SWIG 2.0 to create a Python wrapper for a C++ library. One method has an argument of type \"const std::map&\". SWIG happily generates a wrapper for it, but

相关标签:
1条回答
  • 2020-12-17 19:11

    When you're using a C++ template (e.g. a std::map<string, string>) you need to create an alias for it in your .i file so you can use it in python:

    namespace std {
    %template(map_string_string) map<string, string>;
    }
    

    Now let's say you want to wrap a function that looks like this:

    void foo(const std::map<string, string> &arg);
    

    On the python side, you need to pass a map_string_string to foo, not a python dict. It turns out that you can easily convert a python dict to a map though by doing this:

    map_string_string({ 'a' : 'b' })
    

    so if you want to call foo, you need to do this:

    foo(map_string_string({ 'a' : 'b' }))
    

    Here's full example code that works.

    // test.i
    %module test
    
    %include "std_string.i"
    %include "std_map.i"
    
    namespace std {
        %template(map_string_string) map<string, string>;
    }
    
    void foo(const std::map<std::string, std::string> &val);
    
    %{
    #include <iostream>
    #include <string>
    #include <map>
    
    using namespace std;
    void
    foo(const map<string, string> &val)
    {
        map<string, string>::const_iterator i = val.begin();
        map<string, string>::const_iterator end = val.end();
        while (i != end) {
            cout << i->first << " : " << i->second << endl;
            ++i;
        }
    }
    
    %}
    

    And the python test code:

    #run_test.py
    import test
    
    x = test.map_string_string({ 'a' : 'b', 'c' : 'd' })
    test.foo(x)
    

    And my command line:

    % swig -python -c++ test.i
    % g++ -fPIC -shared -I/usr/include/python2.7  -o _test.so test_wrap.cxx
    % python run_test.py
    a : b
    c : d
    
    0 讨论(0)
提交回复
热议问题