Swig Tutorial

1,976 views
1,881 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,976
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
14
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Swig Tutorial

  1. 1. 想要快一点的方法吗, 使用 swig 吧。假设你有一些 c 你想再加入 Tcl, Perl, Python, Java and C#.。举例来说有这么一个文件 example.c 1 /* File : example.c */ 2 3 #include <time.h> 4 5 double My_variable = 3.0; 6 7 int fact(int n) { 8 if (n <= 1) return 1; 9 else return n*fact(n-1); 10 } 11 12 int my_mod(int x, int y) { 13 14 return (x%y); 15 16 } 17 18 char *get_time() 19 { 20 21 time_t ltime; 22 23 time(&ltime); 24 25 return ctime(&ltime); 26 27 } 28 29 接口文件 现在,为了增加这些文件到你喜欢的语言中, 你需要写一个接口文件(interface file) 投入到 swig 中。这些 C functions 的接口文件可能如下所示:
  2. 2. 1 /* example.i */ 2 3 %module example 4 5 %{ 6 7 /* Put header files here or function declarations like below */ 8 9 extern double My_variable; 10 11 extern int fact(int n); 12 13 extern int my_mod(int x, int y); 14 15 extern char *get_time(); 16 17 %} 18 19 extern double My_variable; 20 21 extern int fact(int n); 22 23 extern int my_mod(int x, int y); 24 25 extern char *get_time(); 26 建立 Tcl 模块 在 UNIX 系统提示,键入以下信息(LINUX 系统请见 SWIG WIKI 共享库页面其他 操作系统帮助): 1 unix % swig -tcl example.i 2 3 unix % gcc -fpic -c example.c example_wrap.c 4 5 -I/usr/local/include 6 7 unix % gcc -shared example.o example_wrap.o -o example.so
  3. 3. 8 9 unix % tclsh 10 11 % load ./example.so example 12 13 % puts $My_variable 14 15 3.0 16 17 % fact 5 18 19 120 20 21 % my_mod 7 3 22 23 1 24 25 % get_time 26 27 Sun Feb 11 23:01:07 1996 28 29 % 该 SWIG 命令创建了一个文件 example_wrap.c,编辑并且和其余的程序联接。在 这情况下,我们必须创建一个动态可装载的链接。能够装载进入 TCL 使用 LOAD 命令。 建立 Python 模块 转换编码 C 成 Python 模块很简单,只需要按如下做即可(请见 SWIG Wiki Shared Libraries(SWIG 共享帮助手册其他操作系统)) 1 unix % swig -python example.i 2 3 unix % gcc -c example.c example_wrap.c 4 5 -I/usr/local/include/python2.1
  4. 4. 6 7 unix % ld -shared example.o example_wrap.o -o _example.so 我们现在可以使用如下 Python 模块。 1 >>> import example 2 3 >>> example.fact(5) 4 5 120 6 7 >>> example.my_mod(7,3) 8 9 1 10 11 >>> example.get_time() 12 13 'Sun Feb 11 23:01:07 1996' 14 15 >>> 建立 Perl 模块 你可以建立如下的 Perl 模块,如 Solaris 请见 SWIG 共享帮助手册其他操作系统) 1 unix % swig -perl5 example.i 2 3 unix % gcc -c example.c example_wrap.c 4 5 `perl -MExtUtils::Embed -e ccopts` 6 7 unix % ld -G example.o example_wrap.o -o example.so 8 9 unix % perl 10 11 use example; 12 13 print $example::My_variable,quot;nquot;; 14 15 print example::fact(5),quot;nquot;;
  5. 5. 16 17 print example::get_time(),quot;nquot;; 18 19 <ctrl-d> 20 21 3.0 22 23 120 24 25 Sun Feb 11 23:01:07 1996 26 27 unix % 建立 Java 模块 SWIG 也会产生 JNI 代码以便 Jave 代码进入 C/CC++。以下是建立一个 Jave 模 块的事例(cygwin ,见 swig 维基共享库页帮助其他操作系统) 1 $ swig -java example.i 2 3 $ gcc -c example.c example_wrap.c -I/c/jdk1.3.1/include -I/c/jdk1.3.1/include/win32 4 5 $ gcc -shared example.o example_wrap.o -mno-cygwin -Wl,--add-stdcall-alias -o example.dll 6 7 $ cat main.java 8 9 public class main { 10 11 public static void main(String argv[]) { 12 13 System.loadLibrary(quot;examplequot;); 14 15 System.out.println(example.getMy_variable()); 16 17 System.out.println(example.fact(5)); 18 19 System.out.println(example.get_time()); 20 21 }
  6. 6. 22 23 } 24 25 $ javac main.java 26 27 $ java main 28 29 3.0 30 31 120 32 33 Mon Mar 4 18:20:31 2002 34 35 $ 建立 C# 模块 SWIG 也会产生代码以便 C#使用 Pinvoke 进入 C/CC++。以下是如何建立 C#模块 事例。cygwin ,见 swig 维基共享库页帮助其他操作系统。使用了开源 DotGNU Portable.NET 能够在大多数 Unix 系统上运行,和其他 C# compilers 一样方便使 用。 1 $ swig -csharp example.i 2 3 $ gcc -c -fpic example.c example_wrap.c 4 5 $ gcc -shared example.o example_wrap.o -o libexample.so 6 7 $ cscc -o runme *.cs 8 9 $ cat runme.cs 10 11 using System; 12 13 public class runme { 14 15 static void Main() { 16 17 Console.WriteLine(example.My_variable);
  7. 7. 18 19 Console.WriteLine(example.fact(5)); 20 21 Console.WriteLine(example.get_time()); 22 23 } 24 25 } 26 27 $ ilrun runme 28 29 3 30 31 120 32 33 Tue May 13 10:45:45 2003 34 35 $ SWIG 懒人方法 如上所见,并非总是需要写一个专门的接口文件。如果你有一个头文件,你可以 直接在其中包含 SWIG 接口,如例: 1 %module example 2 3 %{ 4 5 /* Includes the header in the wrapper code */ 6 7 #include quot;header.hquot; 8 9 %} 10 11 12 13 /* Parse the header file to generate wrappers */ 14 15 %include quot;header.hquot;
  8. 8. 另外,有些人可能只包括 SWIG 条件指令在头文件中。例如: 1 #ifdef SWIG 2 3 %module example 4 5 %{ 6 7 #include quot;header.hquot; 8 9 %} 10 11 #endif 12 13 14 15 extern int fact(int n); 16 17 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...
  9. 9. 上述例子都很简单,但是大体思路已经延伸到复杂的 C/C++。事实上,重 要的是明白 SWIG 一个完整的 C++支持下几乎能包含所有语言的特征。这 些包括预处理,指针,类,甚至 C++模块。SWIG 能够在特定语言打包结 构和类变成 PROXY。 见下列: 为了说明这一点,假设你想要包以下 C++数据结构: 1 // pair.h. A pair like the STL 2 3 namespace std { 4 5 template<class T1, class T2> struct pair { 6 7 T1 first; 8 9 T2 second; 10 11 pair() : first(T1()), second(T2()) { }; 12 13 pair(const T1 &f, const T2 &s) : first(f), second(s) { } 14 15 }; 16 17 } 为了装载 SWIG 你需要如下接口 1 // pair.i - SWIG interface 2 3 %module pair 4 5 %{ 6 7 #include quot;pair.hquot; 8 9 %}
  10. 10. 10 11 12 13 // Ignore the default constructor 14 15 %ignore std::pair::pair(); 16 17 18 19 // Parse the original header file 20 21 %include quot;pair.hquot; 22 23 24 25 // Instantiate some templates 26 27 28 29 %template(pairii) std::pair<int,int>; 30 31 %template(pairdi) std::pair<double,int>; 32 33 现在编译(Python) 1 $ swig -python -c++ pair.i 2 3 $ c++ -c pair_wrap.c -I/usr/local/include/python2.1 4 5 $ c++ -shared pair_wrap.o -o _pair.so 6 7 $ python 8 9 Python 2.1 (#3, Aug 20 2001, 15:41:42)
  11. 11. 10 11 [GCC 2.95.2 19991024 (release)] on sunos5 12 13 Type quot;copyrightquot;, quot;creditsquot; or quot;licensequot; for more information. 14 15 >>> import pair 16 17 >>> a = pair.pairii(3,4) 18 19 >>> a.first 20 21 3 22 23 >>> a.second 24 25 4 26 27 >>> a.second = 16 28 29 >>> a.second 30 31 16 32 33 >>> b = pair.pairdi(3.5,8) 34 35 >>> b.first 36 37 3.5 38 39 >>> b.second 40 41 8

×