C 拓展 Python 实战
使用 setup.py 来打包 C/C++ 模块为 Python Package
新建一个项目目录,结构如下:
py-cmodule-demo # 项目目录
├── demo # 常规的 python module,可以被import 的模块
│ ├── start.py # 可以写入函数
│ ├── __init__.py # 导入需要在该模块下被调用的函数
├── mymath # c 模块目录,可以被import 的模块
│ └── mymath.c # c 模块代码
└── setup.py # 安装脚本
创建mymath.c
/* mymath.c */
#include <Python.h>
PyObject *sum(PyObject *self, PyObject *args) {
int num1, num2;
PyArg_ParseTuple(args, "ii", &num1, &num2);
return Py_BuildValue("i", num1 + num2);
}
static PyMethodDef MymathMethods[] = { //a.python中需要拓展的函数
{"sum", sum, METH_VARARGS, "add up two numbers and return their sum"},
{NULL}
};
static struct PyModuleDef mymath_module = { //b.python中需要拓展的模块
PyModuleDef_HEAD_INIT,
"mymath", //c.模块名称
PyDoc_STR("A hello world example to demonstrate writing a python module in c language"),
-1,
MymathMethods //a.对应函数名称
};
PyMODINIT_FUNC PyInit_mymath(void) { //c.PyInit_模块名称
PyObject *m = PyModule_Create(&mymath_module); //b.对应模块对象的函数名
return m;
}
创建start.py
def hello():
print("module is running")
创建__init__.py
from .demo import start
import mymath
创建setup.py
from setuptools import setup
from setuptools import Extension
mymath = Extension("mymath",
sources=["mymath/mymath.c"],
include_dirs=["/usr/include/python3"], # 编译时需要的 include dirs
library_dirs=["/usr/lib/x86_64-linux-gnu/"] # 编译链接时寻找链接库的目录
)
setup(name="demo", # 我们的 package 的名字
version="1.0", # 版本
description="This is a demo package",
packages=["demo"], # 打包时需要带上的本地 python 包
ext_modules=[mymath] # 打包时需要编译的 c 模块
)
setup.py 安装方式
使用setup.py install安装
sudo python3 setup.py install --record files.txt #安装
cat files.txt |sudo xargs rm -rf #卸载
打包成whl
在dist下生成.whl文件
sudo python3 setup.py bdist_wheel
安装whl文件
pip3 install demo-1.0-cp36-cp36m-linux_aarch64.whl
卸载就像卸载pip包一样
pip3 uninstall demo
使用方式
加载整个python标准包
一个是python函数 ,一个是c拓展函数,通过__init__文件全部加载到demo包下面。