swig介绍及用途说明
SWIG是Simplified Wrapper and Interface Generator的缩写,其官方站点是http://www.swig.org/。SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。SWIG能应用于各种不同类型的语言包括常用脚本编译语言例如Perl, PHP, Python, Tcl, Ruby and PHP。支持语言列表中也包括非脚本编译语言,例如C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), Java, Modula-3, OCAML以及R,甚至是编译器或者汇编的计划应用(Guile, MzScheme, Chicken)。SWIG普遍应用于创建高级语言解析或汇编程序环境,用户接口,作为一种用来测试C/C++或进行原型设计的工具。SWIG还能够导出 XML或Lisp s-expressions格式的解析树。SWIG可以被自由使用,发布,修改用于商业或非商业中。
SWIG是一种简化脚本语言与C/C++接口的开发工具。简而言之,SWIG是一个通过包装和编译C语言程序来达到与脚本语言通讯目的的工具。
因为C/C++的标准正在进步,因此SWIG也是一个不断发展的过程,在1.3版本中支持的特性包括:
-完全支持C99预处理
-所有的ANSI C和C++数据类型
-支持函数、常量、变量
-支持类
-单重或者多重继承
-函数、方法的重载
-运算符重载
-C++模版
-命名空间
-变长传入参数
-C++ 的 smart指针
“非侵入式”创建接口:
对原有的C/C++源代码只需要很小的改动,或者根本不用改动。
将SWIG合并入安装系统:
当我们对原有的source code进行make或者build时,如何巧妙的将SWIG嵌入其中。
这是我们要重点考虑的问题。
自动产生代码:
SWIG通过的input文件的parse,自动生成output文件(wrapped),完全不需要手工
干预。
SWIG试图理解最为复杂的C++语法并将其翻译为一系列简单的接口,而且所有的输出都
符合ANSI C标准,因而可以依赖任意一款编译器进行编译,这也保证了程序人员免于在
调试非标准C/C++语言方面付出的多余劳动。
第5章:SWIG基础
运行SWIG:
敲入swig命令,不带任何参数,就可以看到swig的所有参数输出和详细说明。
输入文件的格式,带.swg或.i后缀名的文件,最常见的格式如下所示:
1
2
3
4
5
6
7
|
%module my_module
%{
#i nclude
%}
extern double result;
void output_throught();
MyClass *my_class;
|
输出文件:
如果没有任何特别参数说明,输出文件包括一个包装source(my_module_wrap.cxx ,一个头文件)。
对C的声明进行简单包装:
处理基本类型问题,int/short/long/unsigned/signed/。
全局变量,SWIG可以将全局变量映射为脚本语言的变量。
指针与复杂对象:
简单的指针,最基本的C数据类型指针。
空指针NULL,被解释为字符串“NULL”或者是0值。
其他实际问题:
带值返回。
structure和union:
SWIG在处理Structure和Union时,存在的技巧和问题。
代码插入:
建立接口的策略。
swig命令常用参数
swig -version 看SWIG开发工具的版本。
swig -java 生成java代码。
swig -help 看帮助。
最佳的学习swig的方法就是到官方网站去看相关文档。
使用swig举例
Python, Perl, Tcl都可以调用C的动态链接库,但必须把它们做成这些脚本语言的扩展模块,这样复杂度又变高了,工作量也大。
SWIG本质上是一个编译器,它可以通过C/C++的头文件或者一个特殊的接口文件来生成一个以_wrap.c为后缀的包装文件,例如你的C模块叫 test.c, 那么SWIG会为你生成一个test_wrap.c文件,然后将这两个文件编译成一个动态链接库,就能使用其它的脚本语言来调用。下面是个简单的例子:
tt.h
1
2
3
4
5
|
#ifdef _WIN32
int
__declspec
(
dllexport
)getvalue();
#else
int
getvalue();
#endif
|
tt.c
1
2
3
4
5
|
#include "tt.h"
int
getvalue()
{
return
100;
}
|
下面使用swig和gcc来生成Python模块,环境:mingw32 + msys. ( http://www.169it.com )
1
2
3
|
swig -python -module tt tt.h
gcc -c tt.c tt_wrap.c -I/usr/local/python25/include
gcc -shared tt.o tt_wrap.o -o tt.dll -L/usr/local/python25/libs -lpython25
|
tt_test_win.py:
1
2
3
|
from
ctypes
import
*
tt
=
CDLL(
"tt.dll"
)
print
tt.getvalue()
|
环境debian下:
1
2
3
|
swig -python -module tt tt.h
gcc -c tt.c tt_wrap.c -I/usr/local/include/python2.5
gcc -shared tt.o tt_wrap.o -o tt.so -L/usr/local/lib/python2.5 -lpython2.5
|
tt_test_linux.py:
1
2
3
|
from
ctypes
import
*
tt
=
CDLL(
"./tt.so"
)
print
tt.getvalue()
|
在以上两个不同的环境下除了一些include和lib的路径不同以及动态连接库的扩展名不同外,代码基本都差不多。这样swig就将从C映射到Python等脚本语言的工作完成了,接下来所做的就是使用Python来测试用C所写的程序。