/* pysample.c */
#include "Python.h"
#define PYSAMPLE_MODULE
#include "pysample.h"
...
/* Destructor function for points */
static void del_Point(PyObject *obj) {
printf("Deleting point\n");
free(PyCapsule_GetPointer(obj,"Point"));
}
/* Utility functions */
static Point *PyPoint_AsPoint(PyObject *obj) {
return (Point *) PyCapsule_GetPointer(obj, "Point");
}
static PyObject *PyPoint_FromPoint(Point *p, int free) {
return PyCapsule_New(p, "Point", free ? del_Point : NULL);
}
static _PointAPIMethods _point_api = {
PyPoint_AsPoint,
PyPoint_FromPoint
};
...
/* Module initialization function */
PyMODINIT_FUNC
PyInit_sample(void) {
PyObject *m;
PyObject *py_point_api;
m = PyModule_Create(&samplemodule);
if (m == NULL)
return NULL;
/* Add the Point C API functions */
py_point_api = PyCapsule_New((void *) &_point_api, "sample._point_api", NULL);
if (py_point_api) {
PyModule_AddObject(m, "_point_api", py_point_api);
}
return m;
}
最后,下面是一个新的扩展模块例子,用来加载并使用这些 API 函数:
/* ptexample.c */
/* Include the header associated with the other module */
#include "pysample.h"
/* An extension function that uses the exported API */
static PyObject *print_point(PyObject *self, PyObject *args) {
PyObject *obj;
Point *p;
if (!PyArg_ParseTuple(args,"O", &obj)) {
return NULL;
}
/* Note: This is defined in a different module */
p = PyPoint_AsPoint(obj);
if (!p) {
return NULL;
}
printf("%f %f\n", p->x, p->y);
return Py_BuildValue("");
}
static PyMethodDef PtExampleMethods[] = {
{"print_point", print_point, METH_VARARGS, "output a point"},
{ NULL, NULL, 0, NULL}
};
static struct PyModuleDef ptexamplemodule = {
PyModuleDef_HEAD_INIT,
"ptexample", /* name of module */
"A module that imports an API", /* Doc string (may be NULL) */
-1, /* Size of per-interpreter state or -1 */
PtExampleMethods /* Method table */
};
/* Module initialization function */
PyMODINIT_FUNC
PyInit_ptexample(void) {
PyObject *m;
m = PyModule_Create(&ptexamplemodule);
if (m == NULL)
return NULL;
/* Import sample, loading its API functions */
if (!import_sample()) {
return NULL;
}
return m;
}