Python C 扩展 参考文档
简述 最近了解了一下Python C 扩展技术,这个技术十分地有用,可以通过C/C++语言为Python赋能,进一步地,通过C/C++调用其他编程语言的过程也是成熟的,因此也可以通过这个方法来调用其他编程语言。当然,这个技术(Python C扩展)本身的一个重要的作用是给原生性能一般的Python编写高性能外部库(例如numpy),通过Python调用高性能的计算库来完成计算。
1 2 3 4 5 6 7 8 9 10 11 12 13 #define PY_SSIZE_T_CLEAN #include <python3.13/Python.h> static struct PyModuleDef Module = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "MyModule" , .m_size = 0 , .m_slots = NULL , .m_methods = NULL }; PyMODINIT_FUNC PyInit_test (void ) { return PyModuleDef_Init(&Module); }
1 2 gcc main.c -shared -o test.so -LPython3 python
通过以上过程,我们就完成了一个Python扩展模块框架的搭建。
新建一个函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #define PY_SSIZE_T_CLEAN #include <python3.13/Python.h> static PyObject* teststr (PyObject* self, PyObject* args) { return PyUnicode_FromString("Hello,World!" ); } static PyMethodDef methods[] = { {"teststr" , teststr, METH_NOARGS, "Retrun a str" }, {NULL , NULL , 0 , NULL } }; static struct PyModuleDef Module = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "MyModule" , .m_size = 0 , .m_slots = NULL , .m_methods = methods }; PyMODINIT_FUNC PyInit_test (void ) { return PyModuleDef_Init(&Module); }
1 2 gcc main.c -shared -o test.so -LPython3 python
1 2 3 >>> import test>>> test.teststr()'Hello,World!'
需要通过static PyMethodDef methods[]定义一个模块方法数组,这个数组暴露出去的就是Python解释器可以调用的这个模块导出的外部函数。
1 2 3 4 5 6 struct PyMethodDef { const char *ml_name; PyCFunction ml_meth; int ml_flags; const char *ml_doc; };
其他 通过Python C扩展,也可以实现一些乱七八糟的玩意儿。举个例子,如果我们预期制作一个完整的软件,并且可以通过整合Python作为脚本语言完成一些事情。(具体来说,比如,做一个编程驱动的游戏)这样我们只需要将Python需要调用的接口通过Python C扩展写好,然后用户就可以通过Python代码调用、二次开发了。(某种程度上,这个属于嵌入Python解释器到一个更大的应用程序的范畴)