顾名思义,就是用C语言编写核心代码,然后封装成PYTHON可以使用的形式,是比较常用的手段之一。
不多废话
需要文件如下:
file1 - 包含C代码,以及封装样板代码的C文件
file2 - setup.py文件,用于编译以及安装
file1 -
必须 #include “Python.h”
//位置-如果装了anaconda则在 anaconda3/include里
//默认在/usr/local/include/python3.x/中
用C定义好函数–比如一个阶乘函数,如果看懂这个函数都有难度的话…
int fac(int n){
if (n<2)
return 1;
else
return (n)*fac(n-1);
}
int main(){
…//中间部分为测试C函数的代码
}
然后是样板函数,样板代码有几个·组成部分:
//1.每个定义的函数都需要一个样板函数
static PyObject* 模块名_函数名(PyObject self,PyObject args){
//用 PyArg_ParseTuple函数解读参数
char * command;
PyObject retval;//定义返回变量
//PyArg_ParseTuple(args,“s”,&command);
//这句话意思为将args解读成char类型存入command位置中
int res;
res = fac(command);//假设函数名叫fac
//用Py_BuildValue来将c变量转换成python变量返回
//Py_BuildValue() returns a tuple
//retval = (PyObject)Py_BuildValue(类型,C变量1,C变量2)
return retval;
}
//2.方法定义-就是该module包含了哪些Methods
static PyMethodDef ExtestMethods[] = { //Extest 为模块名
{“fac”,Extest_fac,METH_VARARGS},
/* python中使用的名称,对应样板函数名称,METH_VARARGS的意思是期待PYTHON-LEVEL的 参数*/
{“doppel”,Extest_doppel,METH_VARARGS},
{NULL,NULL} //表示函数信息结束
};
//3.模块定义
static struct PyModuleDef extestmodule = {
PyModuleDef_HEAD_INIT,
“Extest”, //名称
NULL, //doc
-1, //不懂
ExtestMethods //方法定义
};
//4.启动样板函数
PyMODINIT_FUNC
PyInit_Extest(void){ //Extest为模块名称
PyObject *m;
m = PyModule_Create(&extestmodule); //为模块定义
if(m==NULL)
return NULL;
/可以接触发异常等等/
return m;
}
file 2 :
#setup.py
from distutils.core import setup,Extension
MOD = ‘Extest’ //名称
setup(name=MOD,ext_modules=[Extension(MOD,sources=[‘Extest1.c’])])//源代码·位置
#命令
python setup.py build
python setup.py install //这个执行了之后会将编译生成的库复制到Python安装目录里
/*
Mac-mini:c2python2 admin$ python setup.py install
running install
running build
running build_ext
running install_lib
copying build/lib.macosx-10.6-intel-3.5/Extest.cpython-35m-darwin.so -> /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages
running install_egg_info
Writing /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/Extest-0.0.0-py3.5.egg-info
*/
#附完整代码
//Extest1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Python.h"
int fac(int n){
if (n<2)
return 1;
else
return (n)*fac(n-1);
}
char *reverse(char *s){
register char t,*p=s,*q=(s+(strlen(s)-1));
while(p<q)
{
t = *p;
*p++ = *q;
*q--=t;
}
return s;
}
int main(){
char s[1024];
printf("4!==%d\n",fac(4));
printf("8!==%d\n",fac(8));
printf("12!==%d\n",fac(12));
strcpy(s,"abcdef");
printf("reversing 'abcdef', we get '%s'\n",reverse(s));
strcpy(s,"madam");
printf("reversing 'madam', we get '%s'\n",reverse(s));
return 0;
}
static PyObject * Extest_fac(PyObject *self,PyObject *args){
int num;
if(!PyArg_ParseTuple(args,"i",&num)) return NULL;
return (PyObject*)Py_BuildValue("i",fac(num));
}
static PyObject * Extest_doppel(PyObject *self,PyObject *args){
char* orig_str;
char* dup_str;
PyObject* retval;
if(!PyArg_ParseTuple(args,"s",&orig_str)) return NULL;
retval = (PyObject*)Py_BuildValue("ss",orig_str,dup_str=reverse(strdup(orig_str)));
free(dup_str);
return retval;
}
static PyMethodDef ExtestMethods[] = {
{"fac",Extest_fac,METH_VARARGS},
{"doppel",Extest_doppel,METH_VARARGS},
{NULL,NULL}
};
static struct PyModuleDef extestmodule = {
PyModuleDef_HEAD_INIT,
"Extest",
NULL,
-1,
ExtestMethods
};
PyMODINIT_FUNC
PyInit_Extest(void){
PyObject *m;
m = PyModule_Create(&extestmodule);
if(m==NULL)
return NULL;
return m;
}
#setup.py
from distutils.core import setup,Extension
MOD = 'Extest'
setup(name=MOD,ext_modules=[Extension(MOD,sources=['Extest1.c'])])
在执行了上面说的python setup.py install之后,就可以在Python代码里去调用了。
import Extest
if __name__ == "__main__":
n = Extest.fac(3)
print(n)
m = Extest.doppel("hello")
print(m)
// 运行结果:
// 6
// ('hello', 'olleh')
参考博客: