windows下 用SWIG工具给python封装c/c++库

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.下载SWIG。https://sourceforge.net/projects/swig/

把SWIG添加到环境变量,这样你才能直接打开cmd直接用SWIG,不必cd来cd去。

 

1  原始文件

新建一个文件夹,里面放你的代码吧,不然生成的文件乱七八糟的。

新建这些文件,里面都是空的,直接改后缀名就行。

文件内容:

Zack.cpp (你要包装的C++代码)

/* File: Zack.c */
 
#include "Zack.h"
 
int fact(int n) {
    if (n < 0) return 0;
    if (n == 0) return 1;
    else return n * fact(n-1);
}

 

Zack.h (你要导入的C++头文件)

int fact(int n);

2 编写.i接口文件

这两个是你要的C++的内容,用SWIG就需要告诉她怎么包装。这个文件就是Zack.i(随便什么名字,只要是.i结尾的就行),反正你SWIG命令的时候要指定这个文件。

/* File: Zack.i */
%module Zack
 
%{
#define SWIG_FILE_WITH_INIT
#include "Zack.h"
%}
 
int fact(int n);

.i接口文件中主要包含了三个部分:

  1. %module后面的名字是被封装的模块名称,Python通过这个名称加载程序。
  2. %{...%}之间所添加的内容,一般包含此文件需要的一些函数声明和头文件。
  3. 最后一部分,声明了要封装的函数和变量。

如果把要封装的函数声明部分写在了头文件里,最后一部分直接用%include包含头文件名也行:

/* File: Zack.i */
%module Zack
 
%{
#define SWIG_FILE_WITH_INIT
#include "Zack.h"
%}
 
%include "Zack.h"

两种.i文件的效果是一样的,比较建议使用第二种方法,能够简化接口文件

3 封装代码

然后在当前目录进行包装,出现两个新文件,一个.cxx,一个.py,执行以下命令:

swig -c++ -python Zack.i

如果是c文件,可以直接执行“swig -python Zack.i”。

执行完毕后会生成Zack.py和Zack_wrap.cxx这两个文件,相当于将原cpp文件进行了封装,wrap了一层。

4 生成动态链接库

编写setup.py文件,用于自动化编译动态链接库:

from distutils.core import setup, Extension
 
#生成一个扩展模块(Zack_module )
Zack_module = Extension('_Zack',
                           sources=['Zack_wrap.cxx', #封装后的接口cxx文件
                                    'Zack.cpp'], #以下为原始代码所依赖的文件,源代码从这里引入
                           )
 
setup (name = 'Zack',   #打包后的名称
       version = '0.1',
       author      = "SWIG Docs",
       description = """Zack trial""",
       ext_modules = [Zack_module],  #与上面的扩展模块名称一致
       py_modules = ["Zack"],        #需要打包的模块列表
       )

编写完成后执行以下命令进行编译:

python setup.py build
编译通过后在build/lib.*开头的子目录下即可见到编译好的Python库文件:_Zack.cp37-win_amd64.pyd和Zack.py

至此,编译好的python模组就可以使用了,将_Zack.cp37-win_amd64.pyd和Zack.py复制到你的测试用路径下,编写test.py  ,test.py文件中import Zack就可以了。

 

如果想将该模块安装到Python根目录,可以在刚刚的setup.py路径下用这个命令set up一下,把Zack这段模块安装到Python根目录中即可。(可以不需要执行python setup.py build,直接执行python setup.py install编译安装)

下面一大堆是输出的信息,不用管它。

 

测试一下,在随便一个py文件中import Zack就可以了。

5 编译中可能遇到的报错

在第4步执行python setup.py build编译时可能会遇到以下错误:

error: Unable to find vcvarsall.bat

这是由于python找不到微软自带的编译器导致,需要安装Microsoft Visual C++ compiler,或许你的电脑上已经安装过但仍然报错,这可能是由于你安装的跟python需要的版本不一致,去微软官网下载Visual Studio 2019 生成工具,

https://visualstudio.microsoft.com/zh-hant/visual-cpp-build-tools/

下载安装可能需要1个多 G ,安装后重启电脑重新编译即可。

另外,使用MinGW-w64编译c代码的兄弟,python3.4以上版本不在支持选择这个方式,所以我这里不在推荐。

 

 

参考:

https://blog.csdn.net/Yonggie/article/details/100543900?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值