python 从扩展模块中定义和导出C的API
扩展模块头源代码,pysample.h/*** Created on: 2022年12月30日*/#endif= NULL)?1 : 0;}#endif}#endif扩展模块源代码,ptexample.c/*** Created on: 2022年12月30日*/Point *p;if (!}if (!p) {}}};-1,};if (!}return m;}python编译配置,ptsetup.
·
python 从扩展模块中定义和导出C的API
C语言定义函数库API
- C语言定义函数头源代码,sample.h
/*
* sample.h
*
* Created on: 2022年12月29日
* Author: xzlAwin
*/
extern int gcd(int x, int y);
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);
- C语言实现定义函数源代码,sample.c
/*
* sample.c
*
* Created on: 2022年12月29日
* Author: xzlAwin
*/
#include<math.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;
}
/* A C data structure */
typedef struct Point {
double x,y;
} Point;
/* Function involving a C data structure */
double distance(Point *p1, Point *p2) {
return hypot(p1->x - p2->x, p1->y - p2->y);
}
- C语言暴露函数库API源代码,pysample.c
/*
* pysample.h
*
* Created on: 2022年12月30日
* Author: xzlAwin
*/
#include "Python.h"
#include "sample.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Public API Table */
typedef struct {
Point *(*aspoint)(PyObject *);
PyObject *(*frompoint)(Point *, int);
} _PointAPIMethods;
#ifndef PYSAMPLE_MODULE
/* Method table in external module */
static _PointAPIMethods *_point_api = 0;
/* Import the API table from sample */
static int import_sample(void) {
_point_api = (_PointAPIMethods *) PyCapsule_Import("sample._point_api",0);
return (_point_api != NULL) ? 1 : 0;
}
/* Macros to implement the programming interface */
#define PyPoint_AsPoint(obj) (_point_api->aspoint)(obj)
#define PyPoint_FromPoint(obj) (_point_api->frompoint)(obj)
#endif
#ifdef __cplusplus
}
#endif
- python编译配置,setup.py
from distutils.core import setup, Extension
setup(name="sample",
ext_modules=[
Extension(
"sample",
["sample.c", "pysample.c"],
include_dirs=[".."]
)
]
)
- python命令行,编译函数库,编译成功生成 编译成功生成 sample.cp37-win_amd64.pyd
python3 setup.py build_ext --inplace
扩展模块中的定义
- 扩展模块头源代码,pysample.h
/*
* pysample.h
*
* Created on: 2022年12月30日
* Author: xzlAwin
*/
#include "Python.h"
#include "sample.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Public API Table */
typedef struct {
Point *(*aspoint)(PyObject *);
PyObject *(*frompoint)(Point *, int);
} _PointAPIMethods;
#ifndef PYSAMPLE_MODULE
/* Method table in external module */
static _PointAPIMethods *_point_api = 0;
/* Import the API table from sample */
static int import_sample(void) {
_point_api = (_PointAPIMethods *) PyCapsule_Import("sample._point_api",0);
return (_point_api != NULL) ? 1 : 0;
}
/* Macros to implement the programming interface */
#define PyPoint_AsPoint(obj) (_point_api->aspoint)(obj)
#define PyPoint_FromPoint(obj) (_point_api->frompoint)(obj)
#endif
#ifdef __cplusplus
}
#endif
- 扩展模块源代码,ptexample.c
/*
* ptexample.c
*
* Created on: 2022年12月30日
* Author: xzlAwin
*/
/* 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,
/* name of module */
"ptexample",
/* Doc string (may be NULL) */
"A module that imports an API",
/* Size of per-interpreter state or -1 */
-1,
/* Method table */
PtExampleMethods
};
/* 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;
}
- python编译配置,ptsetup.py
from distutils.core import setup, Extension
setup(name="sample",
ext_modules=[
Extension(
"ptexample",
["ptexample.c"],
include_dirs=["."]
)
]
)
- python命令行,编译函数库,编译成功生成 编译成功生成 ptexample.cp37-win_amd64.pyd
python3 ptsetup.py build_ext --inplace
测试
- python调用库和扩展模块,main.py
import sample
import ptexample
p1 = sample.Point(2, 3)
print(p1)
ptexample.print_point(p1)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献1条内容
所有评论(0)