您的位置:首页 > 编程语言 > Python开发

swig-python

2016-05-30 15:56 375 查看
转载自: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目录,执行一下命令

[plain] view
plain copy

./configure --prefix=/usr/program/swig/ #或者其他安装目录

make

make install

在./configure 时遇到Cannot find pcre-config script from PCRE (Perl Compatible Regular Expressions)的错误,使用

./configure --prefix=/usr/progam/swig --without-pcre, 因为我使用swig的目的是Python

3.SWIG的使用

SWIG支持多种语言(脚本),这里介绍python的一个例子,这个例子是使用c语言模拟位数组,然后交由python扩展

最后有一个使用c扩展python和直接使用python的效率比较

1. 编写c文件

[cpp] view
plain copy

//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

[cpp] view
plain copy

//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

[plain] view
plain copy

%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

[plain] view
plain copy

[username]$ swig -python Bit.i

3.2 编译Bit.c Bit_wrap.c文件,其中PYTHON_INCLUDE为python安装目录下的include文件夹, 如/usr/program/python/include/python.2.7username]$ gcc -c

[plain] view
plain copy

[username]$ gcc -c -fpic Bit.c Bit_wrap.c -I${PYTHON_INCLUDE}

3.3 连接得到动态库

[plain] view
plain copy

[username]$ gcc -shared Bit.o Bit_wrap.o -o _Bit.so

注意输出库文件为_Bit.so, 有下划线和模块名称组成

4.使用,这里以计算一亿一下的素数个数来演示

将Bit.py和_Bit.so文件复制到需要的位置

编写prime_count.py

[python] view
plain copy

#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

使用方法和其他python提供的模块一样

5.附计算结果

使用以上方法(c扩展python)得到结果为:

[html] view
plain copy

5761455(素数个数)

113.465720892(second)

另外,如果直接使用python模拟bit,并同样计算一亿一下的素数个数,结果为

[plain] view
plain copy

5761455(素数个数)

293.473055124(second)

可以看到,性能提升非常明显(接近3倍),当然这只是一个例子,并不具有太多代表性

另附,同样的方法,如果是c语言,调用我们实现的Bit的话结果为:

[plain] view
plain copy

5761455(素数个数)

5(second)

计算这种事情还是交给c做比较恰当
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: