利用swig在python中调用C++代码

很早之前用过swig,可惜长时间不用就忘了当时是怎么用的。

今天刚好写一个非常小的程序,把怎么使用swig在python中调用C++代码记录一下。

程序的目地很简单,有一些实际上是重复的数据,通过映射关系,把不重复的部分抽取出来。

比如序列[0,0,0,1,1,2,2,3,3,3,4,4,4]它映射到[0,3,4,1,2,1,2,0,3,4,0,3,4]。映射表明这两个下标中的数据是相同的。所以最终不重复的数据对应的下标应该是[0,1]。

首先是C++的代码,被写成了一个类。

[code lang=”cpp”]
#include <vector>
#include <set>
#include <map>

class uni{
public:
uni(int n);
void set_k1(int n, int v);
void set_k2(int n, int v);
int uni_size();
int get(int n);
void run();
~uni();
private:
int * k1;
int * k2;
int k_num;
std::set<int> pool;
std::vector<int> ret;
std::multimap<int, int> mapk;
};

uni::uni(int n){
k_num = n;
k1 = new int[n];
k2 = new int[n];
}

void uni::set_k1(int n, int v){
k1[n] = v;
}

void uni::set_k2(int n, int v){
k2[n] = v;
}

int uni::uni_size(){
return ret.size();
}

int uni::get(int n){
return ret[n];
}

void uni::run(){
for(auto i = 0; i < k_num; ++i)
mapk.insert({k1[i], k2[i]});
int max = k1[0];
for(int i = 0; i < k_num; ++i)
if(max < k1[i])
max = k1[i];
for(int i = 0; i < max; ++i) if(pool.find(i) == pool.end()) {
ret.push_back(i);
auto c = mapk.count(i);
auto itr = mapk.find(i);
while(c){
pool.insert(itr->second);
++itr;
–c;
}
}
}

uni::~uni(){
if(k1 != nullptr){
delete k1;
delete k2;
}
}
[/code]

对应的swig脚本的代码如下:

[code]
%module unique
%{
#include "unique.cpp"
%}

%include "unique.cpp"

%pythoncode %{
def unique(k1, k2):
f = uni(len(k1))
for i in range(len(k1)):
f.set_k1(i, k1[i])
f.set_k2(i, k2[i])
f.run()
siz = f.uni_size()
ret = []
for i in range(siz):
ret.append(f.get(i))
return ret
%}[/code]

在终端里使用如下命令编译:
[code gutter=”false” lang=”shell”]swig -python -c++ unique.i[/code]
[code gutter=”false” lang=”shell”]g++ -std=c++11 -fPIC -c unique_wrap.cxx -I /home/zzx/anaconda2/include/python2.7/[/code]
[code gutter=”false” lang=”shell”]g++ -std=c++11 -shared unique_wrap.o -o _unique.so[/code]

之后就可以当作正常的python模块来调用。

Visits: 318

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

*