一、SWIG 之 初识

一、什么是SWIG

1.1 什么是 SWIG

        SWIG (Simplified Wrapper and Interface Generator) 是一种软件开发工具,它将用 C 和 C++ 编写的程序与各种高级编程语言连接起来。SWIG 与不同类型的目标语言一起使用,包括常见的脚本语言,如 Javascript、Perl、PHP、Python、Tcl 和 Ruby。支持的语言列表 还包括非脚本语言,如 C#、D、Go 语言,Java 包括 Android、Lua、OCaml、Octave、Scilab 和 R。还支持几种解释和编译的 Scheme 实现(Guile、MzScheme/Racket)。SWIG 最常用于创建高级解释或编译的编程环境、用户界面,以及作为测试和原型 C/C++ 软件的工具。SWIG 通常用于解析 C/C++ 接口并生成上述目标语言调用 C/C++ 代码所需的"粘合代码"。SWIG 还可以以 XML 的形式导出其解析树。SWIG 是免费软件,SWIG 生成的代码与商业和非商业项目兼容。

1.2 说明

        本文主要参考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 的安装

2.1 SWIG 的下载

官网下载地址: http://www.swig.org/download.html
下载后解压如下图所示:

2.2 SWIG 配置环境变量

2.3 测试 SWIG

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语言的功能。

3.2 visual studio 2013 项目创建

Win32 项目 --> DLL(D) 空项目

具体如下图所示

 

 

3.3 编写C语言

// 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 编写接口文件

3.4.1 编写 .i 接口文件

/* 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包装器代码中。
*/

3.4.2 SWIG 生成 .c 文件和.py 文件

// 在 .i 文件路径下执行下面操作;
swig -python PY_TEST.i 
// 没有任何报错代表生成成功,如下图。生成了一个.i文件中 %module指令定义的文件名的 .py文件 和 %module指令定义的文件名 **_wrap.c 文件

// 然后需要将刚生成的 **_wrap.c 添加到 刚才的项目的 源文件中。

 

 

 

 

3.5 visual studio 2013 环境配置

visual studio 2013 所有的都需要在 release 下 配置

 

 

 

 

 

 

 

 

 

 

3.6 编译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

3.7.2 编写代码,查看数据

# 将刚才生成的 .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)

 

posted on 2022-11-19 12:07  软饭攻城狮  阅读(639)  评论(0编辑  收藏  举报

导航