把C语言写的函数作为python的扩展模块。为python创建扩展需要三个步骤:
1. 创建程序代码(C)
2. 写包装代码
3. 编译(写setup.py进行build)
下面先给出一个最简单的例子的: 计算一个数的二分之一,仅包含两个文件half.c
和setup.py
。先给出这两个例子的全部代码,再详细讲解。这个例子参考了 c-info.ufunc-tutorial
half.c
#include <Python.h>
#include <math.h>
double half(double x)
{
return x/2.;
}
static PyObject* chun_half(PyObject *self, PyObject *args)
{
double x;
// parses the Python argument into a double
if(!PyArg_ParseTuple(args, "d", &x)) {
return NULL;
}
// call function
double y=half(x);
/*This builds the answer back into a python object */
return Py_BuildValue("d", y);
}
static PyMethodDef chunMethods[] = {
{"half",chun_half,METH_VARARGS, "compute half of a number"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"chun",
NULL,
-1,
chunMethods,
NULL,NULL,NULL,NULL
};
PyMODINIT_FUNC PyInit_chun(void)
{
PyObject *m;
m = PyModule_Create(&moduledef);
if (!m) {
return NULL;
}
return m;
}
setup.py
'''
setup.py file for half.c
$python setup.py install
'''
from distutils.core import setup, Extension
module1 = Extension('chun', sources=['half.c'])
setup( name = 'chun',
version='1.0',
description='This is chun package',
ext_modules = [module1])
解析参数
必要参数和缺省参数,“必要参数|缺省参数”
const char *file;
const char *mode = "r";
int bufsize = 0;
if(!PyArg_ParseTuple(args, "s|si", &file, &mode, &bufsize))
{
return NULL;
}
/* A string, and optionally another string and an integer */
/* Possible Python calls:
f('spam')
f('spam', 'w')
f('spam', 'wb', 100000) */