Chinaunix首页 | 论坛 | 博客
  • 博客访问: 38122
  • 博文数量: 22
  • 博客积分: 285
  • 博客等级: 二等列兵
  • 技术积分: 237
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-18 20:02
个人简介

人生最大的悲哀莫过于迷失自我而无法自拔!

文章分类

全部博文(22)

文章存档

2013年(11)

2012年(11)

我的朋友

分类: LINUX

2013-02-01 23:00:09

SWIG
1.概述:
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可以被自由使用,
发布,修改用于商业或非商业中。


2.安装SWIG
1)tar zxvf swig-2.0.9.tar.gz
2)cd swig-2.0.9
3)wget
4)./Tools/pcre-build.sh
5)./configure
6)make && make install




3.用途:
使用SWIG的过程是很简单的,首先确保有一些C语言代码。
1)为代码写接口文件。这很像C语言的头文件(而且,为了更简单,可以直接使用头文件)。
2)为了自动的产生C语言代码(包装代码)要在接口文件上运行SWIG。
3)把原来的C语言代码和产生的包装代码一起编译来产生共享库。


4.示例:
一个简单的用来检测回文的C语言函数(palindrome.C) 
[root@web-db pythonjichu]# cat huiwen.c
#include


int is_palindrome(char *text( {
        int i, n=strlen(text);
        for (i=0;i<=n/2;++i) {
                if (text[i] != text[n-i-1])
                        return 0;
        }
        return 1;
}


Python版本的检测回文的函数:
def is_palindrome(text):
n = len(text)
for i in range(len(text)//2):
if text[i] != text[n-i-1]:
return False
return True


回文库的接口(palindrome.i)
%module is_palindrome
 
 %{
 #include
 %}


extern int is_palindrome(char *text);


运行swig:
[root@web-db pythonjichu]# swig -python palindrome.i
生成两个文件:
palindrome.py和palindrome_wrap.c。 


编译、连接以及使用:
为了能够正确地编译代码,需要知道Python分布版的源代码放在哪(或者,至少要知道pyconfig.h和
Python.h这两个头文件在哪,在我的系统上两个文件存放在:
[root@web-db pythonjichu]# find / -name pyconfig.h
/usr/local/include/python2.7/pyconfig.h
[root@web-db pythonjichu]# find / -name Python.h
/usr/local/include/python2.7/Python.h)
还要根据选择的C语言编译器,将代码编译到一个共享库,指明正确的选项开关。
如果找不出参数和选项开关的正确组合,可以使用另一节的“一条通过编译器的
魔法森林的捷径”。
[root@web-db pythonjichu]# gcc -fPIC -c palindrome.c
[root@web-db pythonjichu]# gcc -fPIC -I/usr/local/include/python2.7/ -c palindrome_wrap.c
[root@web-db pythonjichu]# gcc -shared palindrome.o palindrome_wrap.o -o _palindrome.so
最后得到一个_palindrome.so共享库,她能直接导入python。
[root@web-db pythonjichu]# ls _palindrome.so -l
-rwxr-xr-x 1 root root 49498 Jan 14 22:47 _palindrome.so
[root@web-db pythonjichu]# python
Python 2.7.3 (default, Jan  3 2013, 20:50:15)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import _palindrome
>>> dir(_palindrome)
['SWIG_PyInstanceMethod_New', '__doc__', '__file__', '__name__', '__package__', 'is_palindrome']
>>> _palindrome.is_palindrome('ipreferpi')
1
>>> _palindrome.is_palindrome('notlob')
0
>>>
另外上述产生的palindrome.py是python的包装代码。这个包装了的代码导入了_palindrome
模块并且进行了一些代码检测。如果希望跳过这个步骤,可以移除palindrome.py文件,再
直接把库链接到一个叫palindrome.so的文件上。


使用包装代码的方法和使用共享库一样。
[root@web-db pythonjichu]# python
Python 2.7.3 (default, Jan  3 2013, 20:50:15)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import palindrome
>>> from palindrome import is_palindrome
>>> if is_palindrome('abba'):
...     print 'Wow -- that never occurred to me...'
...
Wow -- that never occurred to me...
>>>


5.引用计数:
在python中,内存管理是自动的---只要创建对象,如果不在使用,他会自动消失。C语言中不是
这样的:必须显示地释放(deallocate)不再使用的对象(或者说是内存块)。如果不那么做,程序
可能开始占据越来越多的内存,这种情况叫做内存泄露(memory leak)。 


当编写python扩展时,需要访问python用来“偷偷地”管理内存的工具,其中之一是引用计数。
思想是:一个对象只要被代码中的某部分引用(用C语言的术语是:还有指针指向那个对象),那么
对象就不应该被释放掉。然后,一个对象的引用数目变为0以后,数据就不会再增加了---没有代码能
创建那个对象的新引用,那个对象在内存中就是“自由浮动的”。这个时候释放它就会很安全。
引用计数会自动完成这个过程:要遵守一定的规则,这些规则是在各种情况下(通过python API的一部分)
有关增加或减少一个对象引用计数的位置的规定,并且当引用计数变为0的时候,对象会被自动释放。
这就意味着没有单独的一段代码对管理一个对象负全部的责任。可以创建一个对象,用一个函数返回他,
然后忘了他就行了。只需要记住当不再使用他的时候,这个对象就会自动消失。


使用两个宏(macro)Py_INCREF和Py_DECREF分别来增加和减少一个对象的引用计数。


不能拥有一个对象,但是可以拥有一个指向他的引用。一个对象的引用计数是指向他的引用的数目。
如果拥有一个引用,应该在不需要这个引用的时候调用Py_DECREF。
如果临时借用(horrow)了一个引用,就不应该在使用完对象后调用Py_DECREF,调用Py_DECREF是引用的
所有者要做的事情。
可以通过调用Py_INCREF将借用的引用变成自己拥有的引用。这将会创建一个新的拥有的引用,而原来的
所有者仍然拥有原来的引用。
当接收到一个作为参数的对象,要不要变换所有者关系或者至少借用,都取决于自己。






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