『Python CoolBook』C扩展库_其二_demo演示
C函数源文件
/* sample.c */ #include "sample.h" /* Compute the greatest common divisor */ int gcd(int x, int y) { int g = y; while (x > 0) { g = x; x = y % x; y = g; } return g; } /* Test if (x0,y0) is in the Mandelbrot set or not */ int in_mandel(double x0, double y0, int n) { double x=0,y=0,xtemp; while (n > 0) { xtemp = x*x - y*y + x0; y = 2*x*y + y0; x = xtemp; n -= 1; if (x*x + y*y > 4) return 0; } return 1; } /* Divide two numbers */ int divide(int a, int b, int *remainder) { int quot = a / b; *remainder = a % b; return quot; } /* Average values in an array */ double avg(double *a, int n) { int i; double total = 0.0; for (i = 0; i < n; i++) { total += a[i]; } return total / n; } /* Function involving a C data structure */ double distance(Point *p1, Point *p2) { return hypot(p1->x - p2->x, p1->y - p2->y); }
C函数头文件
/* sample.h */ #include <math.h> extern int gcd(int, int); extern int in_mandel(double x0, double y0, int n); extern int divide(int a, int b, int *remainder); extern double avg(double *a, int n); typedef struct Point { double x,y; } Point; extern double distance(Point *p1, Point *p2);
Python API封装文件
pysample.c,本文件仅仅封装了前三个标量运算函数,复杂函数交由后续章节介绍
#include "Python.h" #include "sample.h" /* int gcd(int, int) */ static PyObject *sample_gcd(PyObject *self, PyObject *args) { int x, y, result; if (!PyArg_ParseTuple(args,"ii", &x, &y)) { return NULL; } result = gcd(x,y); return Py_BuildValue("i", result); } /* int in_mandel(double, double, int) */ static PyObject *sample_in_mandel(PyObject *self, PyObject *args) { double x0, y0; int n; int result; if (!PyArg_ParseTuple(args, "ddi", &x0, &y0, &n)) { return NULL; } result = in_mandel(x0,y0,n); return Py_BuildValue("i", result); } /* int divide(int, int, int *) */ static PyObject *sample_divide(PyObject *self, PyObject *args) { int a, b, quotient, remainder; if (!PyArg_ParseTuple(args, "ii", &a, &b)) { return NULL; } quotient = divide(a,b, &remainder); return Py_BuildValue("(ii)", quotient, remainder); } /* Module method table */ static PyMethodDef SampleMethods[] = { {"gcd", sample_gcd, METH_VARARGS, "Greatest common divisor"}, {"in_mandel", sample_in_mandel, METH_VARARGS, "Mandelbrot test"}, {"divide", py_divide, METH_VARARGS, "Integer division"}, { NULL, NULL, 0, NULL} }; /* Module structure */ static struct PyModuleDef samplemodule = { PyModuleDef_HEAD_INIT, "sample", /* name of module */ "A sample module", /* Doc string (may be NULL) */ -1, /* Size of per-interpreter state or -1 */ SampleMethods /* Method table */ }; /* Module initialization function */ PyMODINIT_FUNC PyInit_sample(void) { return PyModule_Create(&samplemodule); }
启动文件setup.py
# setup.py from distutils.core import setup, Extension setup(name='sample', ext_modules=[ Extension('sample', ['pysample.c','sample.c'])] )
安装命令
python setup.py install