Chinaunix首页 | 论坛 | 博客
  • 博客访问: 181167
  • 博文数量: 65
  • 博客积分: 1790
  • 博客等级: 上尉
  • 技术积分: 460
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-21 23:51
文章分类
文章存档

2012年(8)

2011年(38)

2010年(19)

分类: Python/Ruby

2011-02-25 00:03:52

想要快一点的方法吗,使用swig吧。假设你有一些c你想再加入Tcl, Perl, Python, Java and C#.。举例来说有这么一个文件example.c

/* File : example.c */

#include
double My_variable = 3.0;

int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}

int my_mod(int x, int y) {
return (x%y);
}

char *get_time()
{
time_t ltime;
time(<ime);
return ctime(<ime);
}

接口文件 现在,为了增加这些文件到你喜欢的语言中,你需要写一个接口文件(interface file)投入到swig中。这些C functions的接口文件可能如下所示:
/* example.i */
%module example
%{
/* Put header files here or function declarations like below */
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
%}

extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
建立Tcl模块 在UNIX系统提示,键入以下信息(LINUX系统请见页面其他操作系统帮助):
unix % swig -tcl example.i
unix % gcc -fpic -c example.c example_wrap.c \
-I/usr/local/include
unix % gcc -shared example.o example_wrap.o -o example.so
unix % tclsh
% load ./example.so example
% puts $My_variable
3.0
% fact 5
120
% my_mod 7 3
1
% get_time
Sun Feb 11 23:01:07 1996

%
该SWIG命令创建了一个文件,编辑并且和其余的程序联接。在这情况下,我们必须创建一个动态可装载的链接。能够装载进入TCL使用LOAD命令。 建立Python模块 转换编码C成Python模块很简单,只需要按如下做即可(请见其他操作系统的帮助手册):

unix % swig -python example.i
unix % gcc -c example.c example_wrap.c \
-I/usr/local/include/python2.1
unix % ld -shared example.o example_wrap.o -o _example.so
我们现在可以使用如下Python模块 :
>>> import example
>>> example.fact(5)
120
>>> example.my_mod(7,3)
1
>>> example.get_time()
'Sun Feb 11 23:01:07 1996'
>>>
建立Perl模块 你可以建立如下的Perl模块,如Solaris(请见其他操作系统的帮助手册):
unix % swig -perl5 example.i
unix % gcc -c example.c example_wrap.c \
`perl -MExtUtils::Embed -e ccopts`
unix % ld -G example.o example_wrap.o -o example.so
unix % perl
use example;
print $example::My_variable,"\n";
print example::fact(5),"\n";
print example::get_time(),"\n";

3.0
120
Sun Feb 11 23:01:07 1996
unix %
建立Java模块 SWIG也会产生JNI代码以便Jave代码进入C/CC++。以下是建立一个Jave模块的事例(cygwin ,见其他操作系统的页帮助):
$ swig -java example.i
$ gcc -c example.c example_wrap.c -I/c/jdk1.3.1/include -I/c/jdk1.3.1/include/win32
$ gcc -shared example.o example_wrap.o -mno-cygwin -Wl,--add-stdcall-alias -o example.dll
$ cat main.java
public class main {
public static void main(String argv[]) {
System.loadLibrary("example");
System.out.println(example.getMy_variable());
System.out.println(example.fact(5));
System.out.println(example.get_time());
}
}
$ javac main.java
$ java main
3.0
120
Mon Mar 4 18:20:31 2002
$
建立C#模块 SWIG也会产生代码以便C#使用Pinvoke进入C/CC++。以下是如何建立C#模块事例。cygwin ,见其他操作系统的页帮助。使用了开源能够在大多数Unix系统上运行,和其他C# compilers一样方便使用:
$ swig -csharp example.i
$ gcc -c -fpic example.c example_wrap.c
$ gcc -shared example.o example_wrap.o -o libexample.so
$ cscc -o runme *.cs
$ cat runme.cs
using System;
public class runme {
static void Main() {
Console.WriteLine(example.My_variable);
Console.WriteLine(example.fact(5));
Console.WriteLine(example.get_time());
}
}
$ ilrun runme
3
120
Tue May 13 10:45:45 2003

$
SWIG 懒人方法 如上所见,并非总是需要写一个专门的接口文件。如果你有一个头文件,你可以直接在其中包含SWIG接口,如例:
%module example
%{
/* Includes the header in the wrapper code */
#include "header.h"
%}

/* Parse the header file to generate wrappers */
%include "header.h"
另外,有些人可能只包括SWIG条件指令在头文件中。例如:
#ifdef SWIG
%module example
%{
#include "header.h"
%}
#endif

extern int fact(int n);
...
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++数据结构:

// pair.h. A pair like the STL
namespace std {
template struct pair {
T1 first;
T2 second;
pair() : first(T1()), second(T2()) { };
pair(const T1 &f, const T2 &s) : first(f), second(s) { }
};
}
为了封装SWIG你需要如下接口:
// pair.i - SWIG interface
%module pair
%{
#include "pair.h"
%}

// Ignore the default constructor
%ignore std::pair::pair();

// Parse the original header file
%include "pair.h"

// Instantiate some templates

%template(pairii) std::pair;
%template(pairdi) std::pair;
接下去是编译(Python):
$ swig -python -c++ pair.i
$ c++ -c pair_wrap.c -I/usr/local/include/python2.1
$ c++ -shared pair_wrap.o -o _pair.so
$ python
Python 2.1 (#3, Aug 20 2001, 15:41:42)
[GCC 2.95.2 19991024 (release)] on sunos5
Type "copyright", "credits" or "license" for more information.
>>> import pair
>>> a = pair.pairii(3,4)
>>> a.first
3
>>> a.second
4
>>> a.second = 16
>>> a.second
16
>>> b = pair.pairdi(3.5,8)
>>> b.first
3.5
>>> b.second
8

转自:
阅读(1042) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~