美文网首页
swig 封装.c

swig 封装.c

作者: 汲晌 | 来源:发表于2014-05-13 17:04 被阅读268次

    http://blog.csdn.net/king_on/article/details/8092399

    http://blog.csdn.net/lcz_ptr/article/details/7824414

    百度搜 python swig ubuntu

    整理

    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  
    
    3.2 编译Bit.c Bit_wrap.c文件,其中PYTHON_INCLUDE为python安装目录下的include文件夹, 如/usr/program/python/include/python.2.7username]$ gcc -c
    [username]$ gcc -c -fpic Bit.c Bit_wrap.c -I${PYTHON_INCLUDE}  
    
    3.3 连接得到动态库
    [username]$ gcc -shared Bit.o Bit_wrap.o -o _Bit.so  
    

    注意输出库文件为_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  
    

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

    5.附计算结果

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

    5761455(素数个数)  
    113.465720892(second)  
    

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

    5761455(素数个数)  
    293.473055124(second)  
    

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

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

    5761455(素数个数)  
    5(second)  

    相关文章

      网友评论

          本文标题:swig 封装.c

          本文链接:https://www.haomeiwen.com/subject/qknrtttx.html