这段时间在摸swig,用它来封装一些后台c++代码,分别生成其他脚本语言(java、python等)可用的api,并总结了swig从安装到配置到生成api的过程,里面也融进了一些网上的资料,还有我自己在实际应用中的感触,留个脚印。 一. SWIG简介: SWIG是Simple Wrapper and Interface Generator的缩写,是一个帮助使用C或者C++编写的软件创建其他编语言的API的工具。例如,我想要为一个C++编写的程序创建.NET API,一般情况下我必须使用托管C++(Managed C++)去编写大量的代码才能生成它的.NET API。有了SWIG,这个机械的工作将变得非常简单。你只须要使用一个接口文件告诉SWIG要为那些类创建.NET API,SWIG就会自动帮你生成它的.NET API。 当然,SWIG不仅仅支持创建.NET API。最新版本的SWIG支持常用脚本语言Perl、PHP、Python、Tcl、Ruby和非脚本语言C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), Java, Modula-3, OCAML以及R,甚至是编译器或者汇编的计划应用(Guile, MzScheme, Chicken)。 二. 环境搭建
1. 下载swigwin,在E:/lib目录下解压,即把swig安装到E:/lib/swig目录中。
2. 新建一个Win32 Console Application,注意在Application Settings中选择DLL以及空项目。完成后将工程的配置改成release
3. 工具-> 选项-> 项目和解决方案-> VC++目录-> 添加E:\lib\swigwin。即把swig添加到VC的可执行目录。
----------------若封装成Python可用的API,执行如下步骤----------------------------
4. 下载python2.5,安装到D:/Program Files目录,并在环境变量PATH中加入D:/Program Files/python2.5。
5. 把D:/Program Files/python2.5/include加入VC的Include路径,将D:/Program Files/python2.5/libs加入VC的Library路径。 -----------------若封装成Java可用的API,执行如下步骤
6. 下载JDK,安装到D:/Program Files目录,并在环境变量PATH中加入D:\Program Files\Java\jdk1.6.0_10\bin(如果之前安装过Oracle,要将D:\Program Files\Java\jdk1.6.0_10\bin放在Oracle\jre\1.3.1\bin前面,否则在编译的时候默认会选择oracle的jdk)
7. 把D:\Program Files\Java\jdk1.6.0_10\include\win32 和D:\Program Files\Java\jdk1.6.0_10\include 加入到加入VC的Include路径。 三. 接口文件
要在C/C++工程中创建***.i 的接口文件,告诉SWIG要为那些类的那些方法创建API。
接口文件注解:
1. 模块名由指定的%module来给出(或者用-module命令行选项).这段指示性文字必须写在文件的头部并且在使用时将这个模块名作为扩展模块对象来使用(此外,这个模块名经常在目标语言中被定义成一个命名空间来使用)。如果模块名在命令行已经被给出了,系统将不考虑由%module标示的模块名了。 对于python:module的名字指定了生成文件xxx.py的xxx名字, 对于java:module的名字指定了生成文件xxx.java的xxx名字
2. 所有在%{...%}块内的东西将被简单作为结果逐字拷贝到SWIG创建的
wrapper(包装)文件中。这部分大部分被用来包括头文件和生成wrapper代码需要的其它声明。这里很重要的强调一点因为你在一个SWIG的输入文件中包含了一个声明,这个声明并不自动显示在生成的wrapper代码中,因此你需要确信你确实把正确的头文件在%{ ... %}部分中。这里应该指出SWIG不解析和解释附在%{ ... %}部分的文字。SWIG的%{...%}内的语法和语义很类似于输入文件中的声明部分。
-------------------------- swig库模块访问部分标准C++库包括STL的方法-------------------
SWIG对于一些语言模块的支持使较全面的但是对很少用到的库则支持的很少。 下面就是表示了C++类和支持的C++库以及SWIG接口文件的对应表 C++ class C++ Library file SWIG Interface library file std::deque deque std_deque.i std::list list std_list.i std::map map std_map.i
std::pair utility std_pair.i std::set set std_set.i
std::string string std_string.i
1. 下载swigwin,在E:/lib目录下解压,即把swig安装到E:/lib/swig目录中。
2. 新建一个Win32 Console Application,注意在Application Settings中选择DLL以及空项目。完成后将工程的配置改成release
3. 工具-> 选项-> 项目和解决方案-> VC++目录-> 添加E:\lib\swigwin。即把swig添加到VC的可执行目录。
----------------若封装成Python可用的API,执行如下步骤----------------------------
4. 下载python2.5,安装到D:/Program Files目录,并在环境变量PATH中加入D:/Program Files/python2.5。
5. 把D:/Program Files/python2.5/include加入VC的Include路径,将D:/Program Files/python2.5/libs加入VC的Library路径。 -----------------若封装成Java可用的API,执行如下步骤
6. 下载JDK,安装到D:/Program Files目录,并在环境变量PATH中加入D:\Program Files\Java\jdk1.6.0_10\bin(如果之前安装过Oracle,要将D:\Program Files\Java\jdk1.6.0_10\bin放在Oracle\jre\1.3.1\bin前面,否则在编译的时候默认会选择oracle的jdk)
7. 把D:\Program Files\Java\jdk1.6.0_10\include\win32 和D:\Program Files\Java\jdk1.6.0_10\include 加入到加入VC的Include路径。 三. 接口文件
要在C/C++工程中创建***.i 的接口文件,告诉SWIG要为那些类的那些方法创建API。
接口文件注解:
1. 模块名由指定的%module来给出(或者用-module命令行选项).这段指示性文字必须写在文件的头部并且在使用时将这个模块名作为扩展模块对象来使用(此外,这个模块名经常在目标语言中被定义成一个命名空间来使用)。如果模块名在命令行已经被给出了,系统将不考虑由%module标示的模块名了。 对于python:module的名字指定了生成文件xxx.py的xxx名字, 对于java:module的名字指定了生成文件xxx.java的xxx名字
2. 所有在%{...%}块内的东西将被简单作为结果逐字拷贝到SWIG创建的
wrapper(包装)文件中。这部分大部分被用来包括头文件和生成wrapper代码需要的其它声明。这里很重要的强调一点因为你在一个SWIG的输入文件中包含了一个声明,这个声明并不自动显示在生成的wrapper代码中,因此你需要确信你确实把正确的头文件在%{ ... %}部分中。这里应该指出SWIG不解析和解释附在%{ ... %}部分的文字。SWIG的%{...%}内的语法和语义很类似于输入文件中的声明部分。
3. 如果打算为类中所有方法创建API,那么有一个非常简单的办法,在接口文件的类声明部分使用%include标记。SWIG将对%include所指定的文件进行语法分析,类中所有公有方法(Public Method)都将在API中暴露。
/* SwigTest.i */
%module SwigTest
%{
#include "SwigTest.h"
%}
%include "SwigTest.h" //不要和#用混-------------------------- swig库模块访问部分标准C++库包括STL的方法-------------------
SWIG对于一些语言模块的支持使较全面的但是对很少用到的库则支持的很少。 下面就是表示了C++类和支持的C++库以及SWIG接口文件的对应表 C++ class C++ Library file SWIG Interface library file std::deque deque std_deque.i std::list list std_list.i std::map map std_map.i
std::pair utility std_pair.i std::set set std_set.i
std::string string std_string.i