一、SWIG 之 初识
一、什么是SWIG
本文主要参考SWIG的官方文档,将原英文文档翻译成中文展示出来(翻译过程参考百度翻译),想看英文原版,需要自己去查看官方文档。简单介绍 C/C++与python之间的数据通信,在嵌入式系统的测试中,可以有效的提高测试效率,需要知道详细的SWIG内容,请自行学习 SWIG的官方手册。
本人根据现实工作中的环境进行修改,与原官方文档使用存在一些出入。 通过 C/C++进行编写相应的代码,然后书写相应的接口文件,通过工具SWIG生成对应的 XXX_wrap.c文件, 接着编译生成 Python能调用的 pyd文件, 最后python调用对应的pyd接口文件。
本文默认用户较为熟悉 C/C++、Python编程语言。C/C++的编译软件为 Visual Stdio 2013, Python的编写工具为 PyCharm Community Edition 2020.1.2。 通过两个软件编写相应代码。
官方文档: http://www.swig.org/Doc4.0/index.html
二、SWIG 的安装
官网下载地址: http://www.swig.org/download.html
下载后解压如下图所示:
swig [ options ] filename
其中 filename 是一个 SWIG 接口文件或一个 C/C++ 头文件。下面是 options 可选范围的子集。也为每一个目标语言定义额外的选项。完整的列表可以通过 swig -help 或 swig -<lang> -help 获得(<lang> 针对特定语言)。
-allegrocl Generate ALLEGROCL wrappers -chicken Generate CHICKEN wrappers -clisp Generate CLISP wrappers -cffi Generate CFFI wrappers -csharp Generate C# wrappers -d Generate D wrappers -go Generate Go wrappers -guile Generate Guile wrappers -java Generate Java wrappers -javascript Generate Javascript wrappers -lua Generate Lua wrappers -modula3 Generate Modula 3 wrappers -mzscheme Generate Mzscheme wrappers -ocaml Generate Ocaml wrappers -octave Generate Octave wrappers -perl Generate Perl wrappers -php5 Generate PHP5 wrappers -php7 Generate PHP7 wrappers -pike Generate Pike wrappers -python Generate Python wrappers -r Generate R (aka GNU S) wrappers -ruby Generate Ruby wrappers -scilab Generate Scilab wrappers -sexp Generate Lisp S-Expressions wrappers -tcl Generate Tcl wrappers -uffi Generate Common Lisp / UFFI wrappers -xml Generate XML wrappers -c++ Enable C++ processing -cppext ext Change file extension of C++ generated files to ext (default is cxx, except for PHP5 which uses cpp) -Dsymbol Define a preprocessor symbol -Fmicrosoft Display error/warning messages in Microsoft format -Fstandard Display error/warning messages in commonly used format -help Display all options -Idir Add a directory to the file include path -lifile Include SWIG library file <ifile> -module name Set the name of the SWIG module -o outfile Set name of C/C++ output file to <outfile> -oh headfile Set name of C++ output header file for directors to <headfile> -outcurrentdir Set default output dir to current dir instead of input file's path -outdir dir Set language specific files output directory -pcreversion Display PCRE version information -swiglib Report location of SWIG library and exit -version Display SWIG version number
三、Visual Studio 中 SWIG的Python调用C、C++的实现
3.1 环境说明
使用环境:
visual studio 2013
Python37 32 位。 因为32的Python可以在32位的电脑和64位上都能使用,所以采用32位的Python
visual studio 2013 支持 win32 和 x64。 为了与Python兼容, 采用 win32本文主要为了python调用C的功能接口。C语言编译环境采用Visual Studio 2013,配置生成 pyd文件。 然后再使用 swig工具,自动生成python调用的接口。然后python调用pyd文件和相关接口,进而python调用C语言的功能。
Win32 项目 --> DLL(D) 空项目
具体如下图所示
// PY_TEST.c int num = 10; double var = 3.0; int fun(int n, int m) { return n + m; } int fact(int n) { if (n <= 1) { return 1; } else { return n * fact(n - 1); } }
3.4 编写接口文件
/* Put headers and other declarations here (将标题和其他声明放在这里) */ /* PY_TEST.i */ %module PY_TEST /* 最终生成的 py文件名称 */ %{ /* Put headers and other declarations here */ extern int num; extern double var; extern int fun(int n, int m); extern int fact(int n); %} extern int num; extern double var; extern int fun(int n, int m); extern int fact(int n); /* 接口文件包含 ISO C 函数原型和变量声明。 %module指令定义将由SWIG创建的模块的名称。 %{%}块提供了一个位置,用于将其他代码(如C头文件或其他C声明)插入到生成的C包装器代码中。 */
// 在 .i 文件路径下执行下面操作; swig -python PY_TEST.i // 没有任何报错代表生成成功,如下图。生成了一个.i文件中 %module指令定义的文件名的 .py文件 和 %module指令定义的文件名 **_wrap.c 文件 // 然后需要将刚生成的 **_wrap.c 添加到 刚才的项目的 源文件中。
重新编译代码,重新生成, 出现如下没有报错代表编译成功。
并且在项目的 Release 文件夹下出现 .pyd 文件 代表生成成功
3.7 编写 Python 接口调用 C 函数接口
3.7.1 查看生成的py文件核心数据内容
# 常规用的函数会正常显示,变量会整合成在一个cvar 变量中 def fun(n, m): return _PY_TEST.fun(n, m) def fact(n): return _PY_TEST.fact(n) cvar = _PY_TEST.cvar
# 将刚才生成的 .pyd 文件和 swig 操作后生成的 .py 文件直接取出,放到 python项目中。, 编写代码直接调用 .py 文件生成的接口函数, .py 文件会自动帮我们调用 .pyd 这个C 语言生成的动态库中的函数, 出现如下结果,代表整个项目成功实现。 import PY_TEST print(PY_TEST.fun(10, 20)) print(PY_TEST.fact(4)) print(PY_TEST.cvar.num) print(PY_TEST.cvar.var)