Python扩展开发。是使用C/C++来编写Python模块,通过导入动态链接库,调用C/C++编写的模块嵌入Python解释器。在编写C/C++的程序时,通过调用Python解释器来执行Python的代码
嵌入Python解释器
编写Demo程序
PyInitialize 初始化Python解释器PyRunSimpleString 执行简单的python语句,打印输出hello worldPyFinalize 释放或销毁解释器1#include23intmain(int argc, char *argv[])4{5 PyInitialize();6 PyRunSimpleString("print(hello world)");7 PyFinalize();8return0;9}编译以及执行程序
1g++ test.cpp -o test \2-I/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m \3-L/Library/Frameworks/Python.framework/Versions/3.7/lib/\4-lpython3.7m56./test思考
如何实现一个动态的执行程序?通过读取Python文件,将文件内容通过传参的方式交付给PyRunSimpleString,这就回归到C/C++中的文件读取的问题了我们可以通过程序传参或者重定向的方式,将 print(hello world)替换为我们想要执行的程序是否可以实现代码热更新呢?通常情况下,我们会耗费大量的时间在编译大型的C/C++程序,如果通过动态加载Python代码的方式,达到我们想要的效果,大大地提升了我们的效率,虽然这会牺牲程序的性能。开发Python内置模块
PyObject* add(PyObject* self, PyObject* args)定义一个静态的方法,返回数据结构 PyObject*在C Python库中,所有的数据类型都为 PyObject*PyArgParseTuple 解析函数 add 的传参ii 表示传入两个 int 类型的数值s 表示传入的一个字符串参数详细说明可以查看参考引用。1MyDemoMethods 为方法声明数组,定义模块方法名,绑定方法,以及方法注释等demomodule 定义模块,模块名称为 demoPyMODINITFUNC PyInitdemo(void)初始化创建模块扩展模块开发
1// demo.cpp 2#include"Python.h"3 4static PyObject* add(PyObject* self, PyObject* args){5int a, b;6if (!PyArgParseTuple(args,"ii",&a,&b)){7returnnullptr;8 }9int sum = a + b;10 PyObject* ret = PyLongFromLong(sum);11return ret;12}1314static PyMethodDef MyDemoMethods[]= {15{"addx", add, METHVARARGS,"add two integers"},16{nullptr, nullptr,0, nullptr},17};1819staticstructPyModuleDefdemomodule ={20 PyModuleDefHEADINIT,21"demo",/* name of module */22NULL,/* module documentation, may be NULL */23-1,/* size of per-interpreter state of the module,24 or -1 if the module keeps state in global variables.*/25 MyDemoMethods26};2728PyMODINITFUNC PyInitdemo(void){29return PyModuleCreate(&spammodule);30}编写python程序,调用动态库模块,执行程序
sys.path.append(./demo.so)加载动态链接库demo.addx 执行模块中的方法 addx 1# test.py 2import sys 34sys.path.append(./demo.so)5 6import demo 78 9defmain():10 print(demo.addx(123,4312))111213if name =="main":14 main()编译以及执行程序
1g++-fpic -c \23 demo.cpp45g++-shared -o demo.so demo.o -lstdc++\6-L/Library/Frameworks/Python.framework/Versions/3.7/lib/-lpython3.7m78python test.py9# output:4435思考
通过C/C++编写Python模块的好处良多。直接调用C/C++编写的程序大大地提升了Python应用程序的性能。总结
无论用C/C++编写Python的模块,还是内置Python解释器,最终的解决方案都需要我们自己评估。需要从应用场景,开发成本,性能、或者效率提升等方面抉择,最终落地。通过底层的学习,让我们更深入地了解Python的实现原理以及应用,在编写Python程序时候会更加注意细节。资料引用
[1] PyArgParseTuple 参数解析
免责声明:本站所有内容及图片均采集来源于网络,并无商业使用,如若侵权请联系删除。