swig入门

来源:互联网 发布:windows.iso怎样安装 编辑:程序博客网 时间:2024/06/03 21:11
最近发现有些漏洞不能扫描,原来是没有需要的库,这些库原来是用SWIG生成的一些接口程序,于是顺便小研究了下这个SWIG是怎么回事。

下面是摘于SWIG中文网:http://swig.minidx.com/

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使用教程
想要快一点的方法吗,使用swig吧。假设你有一些c你想再加入Tcl, Perl, Python, Java and C#.。举例来说有这么一个文件example.c
[cpp] view plain copy
  1. /* File : example.c */  
  2.   
  3. #include <time.h>  
  4. double My_variable = 3.0;  
  5.   
  6. int fact(int n) {  
  7. if (n <= 1) return 1;  
  8. else return n*fact(n-1);  
  9. }  
  10.   
  11. int my_mod(int x, int y) {  
  12. return (x%y);  
  13. }  
  14.   
  15. char *get_time()  
  16. {  
  17. time_t ltime;  
  18. time(<ime);  
  19. return ctime(<ime);  
  20. }  

接口文件 

现在,为了增加这些文件到你喜欢的语言中,你需要写一个接口文件(interface file)投入到swig中。这些C functions的接口文件可能如下所示:

[cpp] view plain copy
  1. /* example.i */  
  2. %module example  
  3. %{  
  4. /* Put header files here or function declarations like below */  
  5. extern double My_variable;  
  6. extern int fact(int n);  
  7. extern int my_mod(int x, int y);  
  8. extern char *get_time();  
  9. %}  
  10.   
  11. extern double My_variable;  
  12. extern int fact(int n);  
  13. extern int my_mod(int x, int y);  
  14. extern char *get_time();  

建立Tcl模块 

在UNIX系统提示,键入以下信息(LINUX系统请见SWIG WIKI共享库页面其他操作系统帮助):

[plain] view plain copy
  1. unix % swig -tcl example.i  
  2. unix % gcc -fpic -c example.c example_wrap.c \  
  3. -I/usr/local/include   
  4. unix % gcc -shared example.o example_wrap.o -o example.so  
  5. unix % tclsh  
  6. % load ./example.so example  
  7. % puts $My_variable  
  8. 3.0  
  9. % fact 5  
  10. 120  
  11. % my_mod 7 3  
  12. 1  
  13. % get_time  
  14. Sun Feb 11 23:01:07 1996  
  15.   
  16. %   

该SWIG命令创建了一个文件example_wrap.c ,编辑并且和其余的程序联接。在这情况下,我们必须创建一个动态可装载的链接。能够装载进入TCL使用LOAD命令。

  建立Python模块

转换编码C成Python模块很简单,只需要按如下做即可(请见其他操作系统的SWIG共享库帮助手册):

[plain] view plain copy
  1. unix % swig -python example.i  
  2. unix % gcc -c example.c example_wrap.c \  
  3. -I/usr/local/include/python2.1  

注:这个路径需视具体情况而定,我的目录在/usr/include/python2.5

[plain] view plain copy
  1. unix % ld -shared example.o example_wrap.o -o _example.so  

我们现在可以使用如下Python模块 :
[plain] view plain copy
  1. >>> import example  
  2. >>> example.fact(5)  
  3. 120  
  4. >>> example.my_mod(7,3)  
  5. 1  
  6. >>> example.get_time()  
  7. 'Sun Feb 11 23:01:07 1996'  
  8. >>>  


建立Perl模块

你可以建立如下的Perl模块,如Solaris(请见其他操作系统的SWIG共享库帮助手册):

[plain] view plain copy
  1. unix % swig -perl5 example.i  
  2. unix % gcc -c example.c example_wrap.c \  
  3. `perl -MExtUtils::Embed -e ccopts`  
  4. unix % ld -G example.o example_wrap.o -o example.so  
  5. unix % perl  
  6. use example;  
  7. print $example::My_variable,"\n";  
  8. print example::fact(5),"\n";  
  9. print example::get_time(),"\n";  
  10. <ctrl-d>  
  11. 3.0  
  12. 120  
  13. Sun Feb 11 23:01:07 1996  
  14. unix %   

建立Java模块

SWIG也会产生JNI代码以便Java代码进入C/C++。以下是建立一个Java模块的事例(cygwin ,见其他操作系统的swig维基共享库页帮助):

[plain] view plain copy
  1. $ swig -java example.i  
  2. $ gcc -c example.c example_wrap.c -I/c/jdk1.3.1/include -I/c/jdk1.3.1/include/win32  
  3. $ gcc -shared example.o example_wrap.o -mno-cygwin -Wl,--add-stdcall-alias -o example.dll  
  4. $ cat main.java  
  5. public class main {  
  6. public static void main(String argv[]) {  
  7. System.loadLibrary("example");  
  8. System.out.println(example.getMy_variable());  
  9. System.out.println(example.fact(5));  
  10. System.out.println(example.get_time());  
  11. }  
  12. }  
  13. $ javac main.java  
  14. $ java main  
  15. 3.0  
  16. 120  
  17. Mon Mar 4 18:20:31 2002  
  18. $  

建立C#模块 

SWIG也会产生代码以便C#使用Pinvoke进入C/C++。以下是如何建立C#模块事例。cygwin ,见其他操作系统的swig维基共享库页帮助。使用了开源DotGNU Portable.NET能够在大多数Unix系统上运行,和其他C# compilers一样方便使用:

[plain] view plain copy
  1. $ swig -csharp example.i  
  2. $ gcc -c -fpic example.c example_wrap.c  
  3. $ gcc -shared example.o example_wrap.o -o libexample.so  
  4. $ cscc -o runme *.cs  
  5. $ cat runme.cs  
  6. using System;  
  7. public class runme {  
  8. static void Main() {  
  9. Console.WriteLine(example.My_variable);  
  10. Console.WriteLine(example.fact(5));  
  11. Console.WriteLine(example.get_time());  
  12. }  
  13. }  
  14. $ ilrun runme  
  15. 3  
  16. 120  
  17. Tue May 13 10:45:45 2003  
  18.   
  19. $  

SWIG 懒人方法 

如上所见,并非总是需要写一个专门的接口文件。如果你有一个头文件,你可以直接在其中包含SWIG接口,如例:

[plain] view plain copy
  1. %module example  
  2. %{  
  3. /* Includes the header in the wrapper code */  
  4. #include "header.h"  
  5. %}  
  6.   
  7. /* Parse the header file to generate wrappers */  
  8. %include "header.h"  
  9.   
  10. //另外,有些人可能只包括SWIG条件指令在头文件中。例如:  
  11. #ifdef SWIG  
  12. %module example  
  13. %{  
  14. #include "header.h"  
  15. %}  
  16. #endif  
  17.   
  18. extern int fact(int n);  
  19. ...  


Microsoft Windows下运行SWIG SWIG能够运行在所有已知的32位版本的WINDOWS下95/98/NT/2000/XP。SWIG通常使用命令提示符因此能够使用NMAKE。模块 通常由DLL编译,可动态加载入Tcl, Python,或者任何你使用的语言。只需要小小加工,SWIG就能够在MS下发挥巨大作用。 That's it (well, more or less) 在开始前,你需要知道的事情。这里是简短的清单:
明确模块名称
使用 ANSI C/C++
理解如何编写一个共享模块/动态连接库(可能需要阅读一些所使用的编译器的帮助文件)
放松
Surely there's more to it... 上述例子都很简单,但是大体思路已经延伸到复杂的C/C++。事实上,重要的是明白SWIG一个完整的C++支持下几乎能包含所有语言的特征。这些包括预处理,指针,类,甚至C++模块。SWIG能够在特定语言打包结构和类变成PROXY。
为了说明这一点,假设你想要封装以下C++数据结构:
[cpp] view plain copy
  1.   
[cpp] view plain copy
  1. // pair.h. A pair like the STL  
  2. namespace std {  
  3. template<class T1, class T2> struct pair {  
  4. T1 first;  
  5. T2 second;  
  6. pair() : first(T1()), second(T2()) { };  
  7. pair(const T1 &f, const T2 &s) : first(f), second(s) { }  
  8. };  
  9. }  
为了封装SWIG你需要如下接口:
[plain] view plain copy
  1. // pair.i - SWIG interface  
  2. %module pair  
  3. %{  
  4. #include "pair.h"  
  5. %}  
  6.   
  7. // Ignore the default constructor  
  8. %ignore std::pair::pair();   
  9.   
  10. // Parse the original header file  
  11. %include "pair.h"  
  12.   
  13. // Instantiate some templates  
  14.   
  15. %template(pairii) std::pair<int,int>;  
  16. %template(pairdi) std::pair<double,int>;  

接下去是编译(Python):
[python] view plain copy
  1. $ swig -python -c++ pair.i  
  2. $ c++ -c pair_wrap.c -I/usr/local/include/python2.1  
  3. $ c++ -shared pair_wrap.o -o _pair.so  
  4. $ python  
  5. Python 2.1 (#3, Aug 20 2001, 15:41:42)   
  6. [GCC 2.95.2 19991024 (release)] on sunos5  
  7. Type "copyright""credits" or "license" for more information.  
  8. >>> import pair  
  9. >>> a = pair.pairii(3,4)  
  10. >>> a.first  
  11. 3  
  12. >>> a.second  
  13. 4  
  14. >>> a.second = 16  
  15. >>> a.second  
  16. 16  
  17. >>> b = pair.pairdi(3.5,8)  
  18. >>> b.first  
  19. 3.5  
  20. >>> b.second  
  21. 8  

c++的程序试了下,没有成功。还需要继续研究。c的倒是已经成功了。感觉这个
工具还是很强大的。以前看过EMC的一个3D图形程序的源代码,里面是直接按照PYTHON
的C/C++扩展实现的,很是复杂。用这个工具真是简单得太多了。
原创粉丝点击