用SWIG向Python提供C++里STL的容器

栏目: 编程工具 · 发布时间: 6年前

内容简介:在Python项目中使用C/C++的代码,除了少数场景,其它都有数据交换的需求。 而C++的本文介绍如何利用C++的

Python 项目中使用C/C++的代码,除了少数场景,其它都有数据交换的需求。 而C++的 vectormap 等,则是常见的数据容器。

本文介绍如何利用 SWIG ,在Python中调用STL的 stringvectormap

string

C++的 string 可以在interface文件里声明时,自动转换成Python文件的 str 。 但是需要在 %module ... 下,声明 %include "std_string.i"

%module example_string

%include "std_string.i"

%{
std::string echo(std::string msg);
%}

std::string echo(std::string msg);

如果只是一些内容简单、结构复杂的数据交换,可以考虑以某种方式序列化为字符串,到上层再解析为Python层的数据结构。 这里展示的是一个返回自身的 echo 函数,实现如下:

#include <string>

using namespace std;

string echo(string msg) {
    return msg;
}

在Python中,调用结果如下:

>>> import example_string
>>> msg = example_string.echo('message')
>>> msg
'message'
>>> isinstance(msg, str)
True

可见,传入和返回,都是Python自带的 str 类型,非常方便。

vector

vector 应该是最常见的顺序容器了。 它比 string 要更麻烦一层,因为模板类是特殊的,需要用 %template 声明一下。

%module example_vector

%include "std_string.i"
%include "std_vector.i"

%{
using namespace std;

vector<string> vector_int2str(vector<int> input);
%}

namespace std {
  %template(StringVector) vector<string>;
  %template(IntVector) vector<int>;
}

using namespace std;

vector<string> vector_int2str(vector<int> input);

Python层会自动生成 StringVectorIntVector 这两个类,作为类型的替代。 这两个类的命名可以随意,它们都实现了 list 的相关协议,可以当作 list 来使用。

示例中的 vector_int2str 函数,就是把 vectorint 转换为 string ,实现如下:

#include <string>
#include <vector>

using namespace std;

vector<string> vector_int2str(vector<int> input) {
    vector<string> result;
    for (vector<int>::const_iterator it = input.begin();
        it != input.end();
        ++it) {
        result.push_back(to_string(*it));
    }
    return result;
}

然而,实际在Python层获取返回值时,却是 tuple 类型。 传入时,也可直接使用 listtuple 等类型——这大概就是动态语言、鸭子类型的魅力吧。

>>> import example_vector
>>> data = example_vector.vector_int2str([1, 2, 3])
>>> data
('1', '2', '3')
>>> isinstance(data, tuple)
True

map

map 是最常见的的关联容器。 和 vector 一起,可以简单表达一切线性数据结构。 与 vector 类似,使用时也需要用 %template 声明。 此外,它还有一个 特殊情况

%module example_map

%include "std_string.i"
%include "std_map.i"

%{
using namespace std;

map<int, string> reverse_map(map<string, int> input);
%}

namespace std {
  %template(Int2strMap) map<int, string>;
  %template(Str2intMap) map<string, int>;
}

using namespace std;

map<int, string> reverse_map(map<string, int> input);

上面的形式,和 vector 类似。 其中, reverse_map 反转了映射关系,示例代码如下:

#include <string>
#include <vector>
#include <map>

using namespace std;

map<int, string> reverse_map(map<string, int> input) {
    map<int, string> result;
    for (map<string, int>::const_iterator it = input.begin();
        it != input.end();
        ++it) {
        result[it->second] = it->first;
    }
    return result;
}

特殊情况就是,虽然 Str2intMapInt2strMap 也实现了 dict 的协议,但是使用时不能直接用Python的 dict

str2int = example_map.Str2intMap()
str2int['1'] = 1
str2int['2'] = 2
str2int['3'] = 3
result = example_map.reverse_map(str2int)
assert isinstance(result, example_map.Int2strMap)
for key, value in result.items():
    assert str2int[value] == key

这就有些不方便了。 不过,虽然没有 vector 方便,但还是可以接受。 换个角度看,也许 vector 才是特殊情况吧。

总结

其它数据结构,比如 listset 等,都有对应的转换方式,这里不一一介绍。

C++ class C++ Library file SWIG Interface library file
std::auto_ptr memory std_auto_ptr.i
std::deque deque std_deque.i
std::list list std_list.i
std::map map std_map.i
std::pair utility std_pair.i
std::set set std_set.i
std::string string std_string.i
std::vector vector std_vector.i
std::array array (C++11) std_array.i
std::shared_ptr shared_ptr (C++11) std_shared_ptr.i

在这些内置 *.i 的支持下,Python与C++的数据交换也变得轻松起来。

参考

以下是相关的官网文档:


以上所述就是小编给大家介绍的《用SWIG向Python提供C++里STL的容器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C++ Concurrency in Action

C++ Concurrency in Action

Anthony Williams / Manning Publications / 2012-2-28 / USD 69.99

HIGHLIGHT C++ Concurrency in Action is the first book to market to show how to take advantage of the new C++ Standard and how to write robust multi-threaded applications in C++. DESCRIPTION With ......一起来看看 《C++ Concurrency in Action》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具