首页 > 代码库 > 使用C语言扩展Python提供性能

使用C语言扩展Python提供性能

python底层是用c写的,c本身是一个非常底层的语言,所以它做某些事情的效率肯定会比上层语言高一些。

比如有些自动化测试用的python库,会对系统的UI进行一些捕获,点击之类的操作,这必然要用到c,实际上这些库就是用c来扩展的。先用c写一些调用系统UI的接口,然后把它封装成python方法。

下面是一个简单的用C来扩展python的例子:

test.c

#include "Python.h"static PyObject *pr_getsum(PyObject *self,PyObject *args){    int n,m;    if(!PyArg_ParseTuple(args,"ii",&n,&m))    return NULL;    return Py_BuildValue("i",m+n);}static PyMethodDef PrMethods[]={{"getsum",pr_getsum,METH_VARARGS,"get the sum"},{NULL,NULL,0,NULL}};void initpr(void){    (void) Py_InitModule("pr",PrMethods);}

上面3个部分缺一不可,主要有:

1. 导出函数:需要注意的是PyArg_ParseTuple(args,"ii",&n,&m)) 这一句,表示python要传入的参数。

                  "i" 表示整数,"d"表示浮点数,“s"表示字符串。

                  要传入2个参数就写"ii","dd","is"等,也可以用多种选择"is|ii"表示第一个参数是整数,第二个可以是字符串或整数

2. 方法列表:PyMethodDef的成员一次表示"方法名,导出函数,参数传递方式,方法描述“

3. 初始化函数:必须以init开头

 然后是编写setup.py文件,与上面的test.c文件在一个目录下

from distutils.core import setup,Extensionmodule = Extension(pr,sources=[test.c])setup(name=pr test,version=1.0,ext_modules=[module])

然后执行命令就可以了

python setup.py build

结束后可以看到生成了一个build目录,里面会有2个文件test.o和pr.so。我们需要用到的是pr.so文件。

可以把pr.so文件放到python的site_packages目录下,或者把pr.so所在的目录添加到sys.path里,就可以在python里直接调用了

import prprint pr.getsum(2,3) 

需要注意的是,在windows上运行python setup.py build的时候可能会报错error: Unable to find vcvarsall.bat 。 这个就自己在google上搜下解决方法吧,linux和mac上应该是可以直接运行的。

 

使用ctypes调用c语言函数

还是上面的例子,我们要求2个数的和。那么在windows上可以这样写

__declspec(dllexport) intadd(int num1, int num2){    return num1 + num2;}

然后是把这个文件编译成动态链接库,这时候需要用到cl命令

cl命令需要安装visual studio,如果已经安装了请按这个方法来配置环境变量http://hi.baidu.com/xiaoma/item/94c649dc4bc5dae3795daac2

然后运行

cl -LD test.c -o test.dll

可以在当前目录下生成一个test.dll文件,这个就是我们要用的。

然后在python文件里就可以直接使用了

from ctypes import *def main():    libtest = cdll.LoadLibrary(test.dll)    print libtest.add(2,3)if __name__ == __main__:    main()

 这个方法在macos x上貌似不行,有待考究

使用C语言扩展Python提供性能