版权声明:本博客系博主原创或转载,允许转载,但请保留原文出处。 https://blog.csdn.net/heivy/article/details/51133725
扩展python
步骤
1、创建应用程序代码
2、利用样板来包装代码
3、编译和测试
1.1 纯C版本库(Extest1.c)
#include<stdio.h>
#include<stdlib.h>
int fac(int n)
{
if (n<2) return(1); /* 0! == 1! == 1*/
return (n)*fac(n-1);
}
int main()
{
printf("4! == %d/n" , fac(4));
printf("8! == %d/n" , fac(8));
printf("12! == %d/n" , fac(12));
}
2.1样板主要分四步:
1、包含python的头文件
在代码中加入一行: #include "python.h"
2、为每个模板的每一个函数增加一个形如PyObject* Module_func()的包装函数
比如,希望python中可以导入(import)fac()函数,其所在的模块名为Extest,
那么我们就要创建一个包装函数:Extest_fac()
完整的Extest_fac()函数:
static PyObject*
Extest_fac(PyObject *self, PyObject *args)
int res;
int num;
PyObject* retval;
res = PyArg_ParseTuple(args, "i", &num);
if(!res) { // TypeError
return NULL;
}
res = fac(num);
retval = (PyObject*) Py_buildValue("i",res);
return retval;
3、为每个模板的每一个函数增加一个形如PyMethodDefault ModuleMethods[] 的数组
为Extest模块创建一个 ExtestMethods[]数组:
static PyMethodDef
ExtestMethods[] = {
{ "fac", Extest_fac, METH_VARARGS },
{ NULL,NULL},
};
##每一个数组都包含函数在python中的名字,相应的包装函数的名字和一个 METH_VARARGS常量
4、增加模板初始化函数 void initModule()
void initExtest(){
Py_InitModule("Extest",ExtestMethods);
}
到此,我们把 1.1的Extest1.c 文件和 2.1 中的所有代码合并到一个新文件:Extest2.c
3编译
使用 distutils 包
1、创建 setup.py
2、通过运行setup.py 来编译和连接代码
3、从python中导入模块
4、测试功能
3.1
创建一个 setup.py,为能编译扩展,要为每一个扩展创建一个Extension 实例,
Extension('Extest',sources=['Extest2.c'])
调用 setup(),setup()需要2个参数:一个名字参数表示要编译哪个东西,
一个列表列出要编译的对象,语法如下:
setup('Extest',ext_modules=['Extest2.c'])
下面这个脚本会把扩展编译到bulid/lib.*子目录中
#!/usr/bin/env python
from distutils.core import setup, Extension
MOD = 'Extest'
setup(name=MOD,ext_modules=[
Extension(MOD,sources['Extest2.c'])])
3.2
命令:
python setup.py build
3.3 导入和测试
命令:
python setup.py install
import Extest
Extest.fac(5)
最后
把main() 函数改为 test(),添加一个 Extest_test()函数把它包装起来,
然后在ExtestMethods 中加入这个函数。
static PyObject*
Extest_test(PyObject *self, PyObject *args){
test();
return (PyObject*) Py_BuildValue("");
}
本文出自“he ivy”的博客,转载请务必保留此出处:http://blog.csdn.net/heivy/article/details/51133725