当前位置:   article > 正文

Swig:C/C++代码转Python_swig c++转python

swig c++转python

下面用一个简单的小例子来说明,C++的源代码如下:(这里用到了C++11的特性)

//kmodel.hpp
#ifndef KMODEL_H
#define KMODEL_H

#include <string>
#include <iostream>
#include <unordered_map>
#include <stdint.h>

class KModel{
public:
    KModel(){
        umap["123"]=1024;
        umap["name"]=2048;
    }
    std::unordered_map<std::string,int> umap; 
    void say(std::string v);
};
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
//kmodel.cpp
#include "kmodel.hpp"
using namespace std;

void KModel::say(string v){
    cout<<umap[v]<<endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Swig下载地址,目前使用的是Swig-3.0.12

1.编写转换规则kmodel.i

%module kmodel 
%include "std_string.i"
%{
    #include "kmodel.hpp"
%}
%include "kmodel.hpp"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

%include “kmodel.hpp”,表示类或函数的声明,可以直接添加进来。另外需要添加%include “std_string.i”,是因为say方法的参数是string类型,所以要添加string的头文件,若不添加会出现下面的错误

TypeError: in method 'KModel_say', argument 2 of type 'std::string'
  • 1

通常你的接口用了什么类型,最好都把其头文件添加上去,下面是C++类、C++库 以及SWIG接口文件的对应表

C++ classC++ Library fileSWIG Interface library file
std::dequedequestd_deque.i
std::listliststd_list.i
std::mapmapstd_map.i
std::pairutilitystd_pair.i
std::setsetstd_set.i
std::stringstringstd_string.i
std::vectorvectorstd_vector.i


2.生成中间文件

swig -c++ -python kmodel.i
  • 1

上面的代码会生成2个中间文件:
kmodel.py :在Python中import包时会用到
kmodel_wrap.cxx:编译C++时会用到

3.使用distutils工具编译

"""
setup.py
"""
from distutils.core import setup, Extension
setup(name = "kmodel", version = "1.0", 
    ext_modules = [Extension("_kmodel", ["kmodel_wrap.cxx", "kmodel.cpp"],extra_compile_args = ['-std=c++11'])],
    py_modules=['kmodel'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这个格式是固定的,注意命名和额外的编译参数,然后编译安装

python setup.py install
  • 1

进入python命令行进行测试:

>>> from kmodel import *
>>> k=KModel()
>>> k.say("123")
1024
  • 1
  • 2
  • 3
  • 4

注意的问题:
1)C++类中声明的方法必须有实现,只声明不实现会出现下面的错误

ImportError: /usr/local/anaconda3/lib/python3.6/site-packages/_kmodel.cpython-36m-x86_64-linux-gnu.so: undefined symbol: _ZN9ModelTool17getFormatFileSizeEm
  • 1

2)GCC版本必须和Python的底层GCC版本保持一致,否则出现下面的错误

 undefined symbol: _ZSt24__throw_out_of_range_fmtPKcz
  • 1

解决的方法可以升级当前的Python的GCC版本,比如我使用的是anaconda3,升级GCC的命令如下:

conda install libgcc 
  • 1

参考:
http://www.cnblogs.com/kaituorensheng/p/4464117.html
http://blog.csdn.net/earbao/article/details/10473329
https://www.zhihu.com/question/56272908

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/555693
推荐阅读
相关标签
  

闽ICP备14008679号