转载自:http://blog.csdn.net/king_on/article/details/8092399
1. SWIG介绍(来自于wiki)
SWIG (Simplified Wrapper and Interface Generator) is anopen source software tool used to connectcomputer programs or libraries written in C or C++ with scripting languages such as Lua, Perl, PHP, Python, R,Ruby, Tcl, and other languages likeC#, Java, Go, Modula-3,OCaml, Octave, and Scheme. Output can also be in the form of XML or Lisp S-expressions.
2.SWIG的安装
2.1 下载地址: http://www.swig.org/download.html
2.2 将下载的文件如swig-2.0.8.tar.gz解压
2.3 进入swig-2.0.8目录,执行一下命令
- ./configure --prefix=/usr/program/swig/ #或者其他安装目录
- make
- make install
./configure --prefix=/usr/progam/swig --without-pcre, 因为我使用swig的目的是Python
3.SWIG的使用
SWIG支持多种语言(脚本),这里介绍python的一个例子,这个例子是使用c语言模拟位数组,然后交由python扩展
最后有一个使用c扩展python和直接使用python的效率比较
1. 编写c文件
- //Bit.h
- #ifndef BIT_H
- #define BIT_H
- //create: 2012-10-19
- //version: 1.0
- #define CHAR_LENGTH sizeof(unsigned char)
- //Bit模拟位操作
- typedef struct
- {
- unsigned char *pArray;//指向一个字符型数组,用以存储bit位
- unsigned long length;//记录pArray的长度, 字符个数
- unsigned long used;//记录用户使用的bit位
- }Bit;
- //创建Bit对象
- //@len: 初始化bit位数
- //@return: 返回一个指向Bit对象的指针, 该指针需要使用freeBit销毁
- Bit* createBit(unsigned long len);
- //设置bit位
- //@pb:指向Bit的一个对象, 如果为NULL, 返回1
- //@index: 需要设置的bit位, 范围应当是 (0~used)
- //@value: bit位的值, (0,1)
- //@return: 成功返回0, 如果出现pb==NULL, index out of range, value!=0 and value!=1, 返回1
- int setBit(Bit *pb,unsigned long index, int value);
- //获取bit位
- //@pb:指向Bit的一个对象, 如果为NULL, 返回1
- //@index: 需要设置的bit位, 范围应当是 (0~used)
- //@return: 成功返回0, 如果出现pb==NULL, index out of range, 返回1
- int getBit(Bit *pb,unsigned long index);
- //返回使用的长度
- //@pb: 如果pb==NULL, return -1
- int bitLength(Bit *pb);
- //销毁Bit对象
- void freeBit(Bit *pb);
- #endif
- //Bit.c
- #include "Bit.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <limits.h>
- //创建Bit对象
- //@len: 初始化bit位数, len>=0
- //@return: 返回一个指向Bit对象的指针, 该指针需要使用freeBit销毁
- Bit* createBit(unsigned long len)
- {
- if(len<0)
- return NULL;
- Bit *pb=(Bit*)malloc(sizeof(Bit));
- if(len>0)
- {
- pb->length=(len-1)/CHAR_LENGTH+1;
- pb->pArray=(char*)malloc(sizeof(char)*pb->length);
- pb->used=len;
- }else
- {
- pb->length=0;
- pb->pArray=NULL;
- pb->used=len;
- }
- return pb;
- }
- //设置bit位
- //@pb:指向Bit的一个对象, 如果为NULL, 返回1
- //@index: 需要设置的bit位, 范围应当是 [0~used)
- //@value: bit位的值, (0,1)
- //@return: 成功返回0, 如果出现pb==NULL, index out of range, value!=0 and value!=1, 返回1
- int setBit(Bit *pb,unsigned long index, int value)
- {
- if(pb==NULL || pb->pArray==NULL || index<0 || index>=pb->used || (value!=0 && value!=1))
- return 1;
- unsigned long a=index/CHAR_LENGTH;
- unsigned long b=index%CHAR_LENGTH;
- if(value==0)
- {
- pb->pArray[a]&=(UCHAR_MAX^(1<<b));
- //printf("%d\n",pb->pArray[a]);
- }else
- {
- pb->pArray[a]|=(1<<b);
- //printf("%d\n",pb->pArray[a]);
- }
- return 0;
- }
- //获取bit位
- //@pb:指向Bit的一个对象, 如果为NULL, 返回1
- //@index: 需要设置的bit位, 范围应当是 [0~used)
- //@return: 成功返回0, 如果出现pb==NULL, index out of range, 返回1
- int getBit(Bit *pb,unsigned long index)
- {
- if(pb==NULL || pb->pArray==NULL || index<0 || index>=pb->used)
- return 1;
- unsigned long a=index/CHAR_LENGTH;
- unsigned long b=index%CHAR_LENGTH;
- //printf("%d\n",pb->pArray[a]&(1<<b));
- if((pb->pArray[a]&(1<<b))==0)
- return 0;
- else
- return 1;
- }
- //返回使用的长度
- //@pb: 如果pb==NULL, return -1
- int bitLength(Bit *pb)
- {
- if(pb==NULL || pb->pArray==NULL)
- return -1;
- return pb->used;
- }
- //销毁Bit对象
- void freeBit(Bit *pb)
- {
- if(pb==NULL)
- return;
- if(pb->pArray!=NULL)
- {
- free(pb->pArray);
- pb->pArray=NULL;
- }
- free(pb);
- }
2. 编写SWIG使用的swg文件
//Bit.i
- %module Bit #module name
- %{
- #include "Bit.h" #加入Bit_wrap.c文件
- %}
- #需要导出到python的函数
- extern Bit* createBit(unsigned long len);
- extern int setBit(Bit *pb,unsigned long index, int value);
- extern int getBit(Bit *pb,unsigned long index);
- extern int bitLength(Bit *pb);
- extern void freeBit(Bit *pb);
3. 编译
3.1 使用Bit.i生成wrap文件,该命令得到Bit_wrap.c Bit.py
- [username]$ swig -python Bit.i
- [username]$ gcc -c -fpic Bit.c Bit_wrap.c -I${PYTHON_INCLUDE}
- [username]$ gcc -shared Bit.o Bit_wrap.o -o _Bit.so
4.使用,这里以计算一亿一下的素数个数来演示
将Bit.py和_Bit.so文件复制到需要的位置
编写prime_count.py
- #coding=utf-8
- #create-2012-10-17
- #version: 1.0
- #计算小于1亿的素数个数
- import time
- from Bit import *
- MAX=100000000
- count=1
- #0 表示素数
- #1 表示已经去除
- start_time=time.time()
- len=MAX/2-1
- b=createBit(len)
- def remove(idx):
- i=idx
- global b
- while i<len:
- #b[i]=1
- setBit(b,i,1)
- i+=2*idx+3
- for i in range(3,MAX,2):
- if getBit(b,(i-3)/2)==0:
- #素数
- count+=1
- remove((i-3)/2)
- end_time=time.time()
- print count
- print end_time-start_time
5.附计算结果
使用以上方法(c扩展python)得到结果为:
- 5761455(素数个数)
- 113.465720892(second)
- 5761455(素数个数)
- 293.473055124(second)
另附,同样的方法,如果是c语言,调用我们实现的Bit的话结果为:
- 5761455(素数个数)
- 5(second)
计算这种事情还是交给c做比较恰当