使用SWIG实现Python调用C/C++代码
2017-03-29 17:25
1091 查看
原文地址
SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。
SWIG能应用于各种不同类型的语言,包括常用脚本编译语言,例如Perl, PHP, Python,
Tcl, Ruby 和 PHP。
SWIG普遍应用于创建高级语言解析或汇编程序环境、用户接口、作为一种用来测试C/C++或进行原型设计的工具。
工作中碰到了一个小问题:有一个加密/解密的程序原本是用C++语言写的,后来需要用Python来实现调用。简单粗暴的办法是照着C++代码重写一个Python版本的程序,但是很麻烦,还会带来以下问题:
时间成本,开发方面需要些代价
维护成本,需要自己维护,重复造轮子
代码冗余,多套代码,不易维护
后来经老手介绍,知道可以用SWIG来把C++的代码封装成Python库,供Python调用。
SWIG (Simplified Wrapper and Interface Generator) 是用来为C和C++程序构造脚本语言接口的软件开发工具。SWIG 实际上是一个编译器,获取C/C++的声明,用一个壳包起来,以便通过其他语言访问这些声明。因此,SWIG 最大的好处就是将脚本语言的开发效率和 C/C++ 的运行效率结合起来。
编写好原始的h和cpp文件,示例如下:
新增加文件EncryptTool.i,内容如下:
.i接口文件中主要包含了三个部分:
最后一部分,声明了要封装的函数和变量。
如果把要封装的函数声明部分写在了头文件里,最后一部分直接用
两种.i文件的效果是一样的,比较建议使用第二种方法,能够简化接口文件
执行以下命令对c++代码进行封装:
执行完毕后会生成EncryptTool.py和EncryptTool_wrap.cxx这两个文件,相当于将原cpp文件进行了封装,wrap了一层
编写setup.py文件,用于自动化编译动态链接库:
编写完成后执行以下命令进行编译:
编译通过后在
通过以下方式调用所生成的动态链接库即可:
SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。
SWIG能应用于各种不同类型的语言,包括常用脚本编译语言,例如Perl, PHP, Python,
Tcl, Ruby 和 PHP。
SWIG普遍应用于创建高级语言解析或汇编程序环境、用户接口、作为一种用来测试C/C++或进行原型设计的工具。
工作中碰到了一个小问题:有一个加密/解密的程序原本是用C++语言写的,后来需要用Python来实现调用。简单粗暴的办法是照着C++代码重写一个Python版本的程序,但是很麻烦,还会带来以下问题:
时间成本,开发方面需要些代价
维护成本,需要自己维护,重复造轮子
代码冗余,多套代码,不易维护
后来经老手介绍,知道可以用SWIG来把C++的代码封装成Python库,供Python调用。
SWIG (Simplified Wrapper and Interface Generator) 是用来为C和C++程序构造脚本语言接口的软件开发工具。SWIG 实际上是一个编译器,获取C/C++的声明,用一个壳包起来,以便通过其他语言访问这些声明。因此,SWIG 最大的好处就是将脚本语言的开发效率和 C/C++ 的运行效率结合起来。
1 原始文件
编写好原始的h和cpp文件,示例如下:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //File: EncryptTool.h int EncryptFile(const char *szInputFile, const char *szOutputFile); int DecryptFile(const char *szInputFile, const char *szOutputFile); //File: EncryptTool.cpp int EncryptFile(const char *szInputFile, const char *szOutputFile) { ... //省略实现代码 } int DecryptFile(const char *szInputFile, const char *szOutputFile) { ... //省略实现代码 } |
2 编写.i接口文件
新增加文件EncryptTool.i,内容如下:1 2 3 4 5 6 7 8 9 | //File: EncryptTool.i %module EncryptTool %{ #define SWIG_FILE_WITH_INIT #include "EncryptTool.h" %} int EncryptFile(const char *szInputFile, const char *szOutputFile); int DecryptFile(const char *szInputFile, const char *szOutputFile); |
%module后面的名字是被封装的模块名称,Python通过这个名称加载程序。
%{...%}之间所添加的内容,一般包含此文件需要的一些函数声明和头文件。
最后一部分,声明了要封装的函数和变量。
如果把要封装的函数声明部分写在了头文件里,最后一部分直接用
%include包含头文件名也行:
1 2 3 4 5 6 7 8 | //File: EncryptTool.i %module EncryptTool %{ #define SWIG_FILE_WITH_INIT #include "EncryptTool.h" %} %include "EncryptTool.h" |
3 封装代码
执行以下命令对c++代码进行封装:1 | swig -python -c++ EncryptTool.i |
4 生成动态链接库
编写setup.py文件,用于自动化编译动态链接库:1 2 3 4 5 6 7 8 9 10 11 12 13 14 1516 | #File: setup.py #!/usr/bin/python2.7 from distutils.core import setup, Extension #生成一个扩展模块 pht_module = Extension('_EncryptTool', #模块名称,必须要有下划线 sources=['EncryptTool_wrap.cxx', #封装后的接口cxx文件 'base32.cpp', #以下为原始代码所依赖的文件 'BlowFish.cpp', 'CyFile.cpp', 'CyHash.cpp', 'Encrypt.cpp', 'EncryptTool.cpp', 'md5.cpp', 'sha1.cpp', 'stdafx.cpp' ], ) setup(name = 'EncryptTool', #打包后的名称 version = '0.1', author = 'SWIG Docs', description = 'Simple swig pht from docs', ext_modules = [pht_module], #与上面的扩展模块名称一致 py_modules = ['EncryptTool'], #需要打包的模块列表 ) |
1 | python setup.py build |
build/lib.*开头的子目录下即可见到编译好的Python库文件:_EncryptTool.so和EncryptTool.py
5 在Python加载库
通过以下方式调用所生成的动态链接库即可:12 | import EncryptTool EncryptTool.EncryptFile( "data.xml" , "data.pyblf" ) #加密 EncryptTool.DecryptFile( "data.pyblf" , "data.pyxml" ) #解密 |
相关文章推荐
- 用Swig将c/c++程序转为java代码(使用swig实现java调用c、c++的方法)
- linux下使用SWIG实现Python调用C++ sdk读取相机图片
- centos中使用swig实现python调用c++
- centos7下使用swig扩展python接口来调用c++ 实现声纹识别
- 使用swig在python中调用c++代码
- 通过SWIG封装C/C++代码被Python调用
- 利用swig实现python调用C/C++的方法
- Python调用C/C++(使用SWIG)
- 使用boost实现c++与python的相互调用
- 使用swig实现C++的python扩展功能
- 利用Swig在python中调用C/C++代码
- 利用swig实现python调用C/C++的方法
- windows下用swig实现python调用C\C++的方法
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法实现边缘检测代码(2)
- 使用SWIG实现C/C++与其他语言间的互相调用
- 使用Visual Studio,几步实现Python C++扩展,以及DLL调用
- Windows下python使用SWIG调用C++ dll
- 查看python调用c++代码的代码实现位于那个cpp文件
- 使用 SWIG 实现 Java 调用 C++ DLL
- 使用SWIG实现C/C++与其他语言间的互相调用 zz