当前位置: 首页 > 后端技术 > PHP

C++开发pythonwindows版本扩展模块实例

时间:2023-03-29 21:40:09 PHP

C++开发pythonwindows版本扩展模块实例测试环境介绍及准备测试环境:操作系统:windows10Python版本:3.7.0VS版本:vs2015社区版(免费)相关工具下载:VS版vs2015社区版(免费)win10SDK(安装vs2015是可选的,如果没有安装,需要单独安装)Python3.7.0win32安装文件http://ffmpeg.club/python本例没有使用vs编辑,但是需要安装vs的编译环境,直接用python的distutils编译安装。注意这里安装的python是32位的,所以编译出来的库也是32位的程序。首先检查系统中是否还有其他python版本,防止冲突。输入python命令行importsysprint(sys.path)查看当前系统路径是否正确。如果是其他路径的版本,可能会影响扩展库的开发。主要问题是库文件、头文件、dll文件不一致。1头文件和库文件首先创建文件mymod.c在文件中添加头文件引用头文件??引用#include"Python.h",库文件不需要指定,头文件路径在python中安装路径。2定义模块功能。函数参数self是模块本身,args是python传递的参数列表,返回值定义了一个整数0。这里会申请空间增加引用计数,引用由python管理。这里也可以返回NULL,python会收到异常。include"Python.h"///ModulefunctionstaticPyObjecttestmod(PyObjectself,PyObject*args){//返回python的长整型,c语言中引用计数+1,返回值由python释放returnPyLong_FromLong(0);}3声明模块函数(对python开放)。第一个函数名是给python开放的名字。不一定要和c语言中的函数名一样,但尽量保持一致,方便后续代码;第二个是函数指针,默认类型是PyCFunction函数指针类型,也就是上面的函数类型;第三个参数是对python开放的函数参数类型,这里我们不设置参数METH_NOARGS,也可以设置多个METH_VARARGS参数,METH_KEYWORDS键值参数,设置为METH_KEYWORDS必须和METH_VARARGS一起设置METH_KEYWORDS|METH_VARARGS,模块函数将添加一个参数,用于存放传入的参数字典;第四个参数是函数描述,可以调用python中的帮助函数读取;这个定义是一个数据,可以设置多个函数PyMethodDef定义对象///模块函数列表staticPyMethodDefmymod_funcs[]={{"testmod",//函数名testmod,//函数指针METH_NOARGS,//参数标识无参数,"testmodfunction."//函数说明help(testmod)},{0,0,0,0}//数组末尾可以申请多个函数};4模块定义///4模块定义staticPyModuleDefmymod_module={PyModuleDef_HEAD_INIT,"mymod",//模块名称"mymodisfirstmoduletest",//moduledescriptionviahelp(modulename)-1,//模块空间,forsub-interpreter,-1doesnotusemymod_funcs//modulefunction,functiondefinedearlierdeclarethearray};5添加入口函数,其中PyMODINIT_FUNC宏为PyMODINIT_FUNC__declspec(dllexport)PyObject*inwindows,即入口与ctypes库不同,只有扩展库的入口函数需要定义__declspec(dllexport)导出函数符号,其他函数不需要PyModule_Create创建python模块,参数为前面定义的模块,直接返回返回模块对象,python中所有类型都可以转换为PyObject///1扩展库入口函数PyInit_固定开头mymod模块名PyMODINIT_FUNCPyInit_mymod(void){printf("PyInit_mymodn");///2模块创建函数参数PyModuleDefreturnPyModule_Create(&mymod_module);}6编译安装并创建一个文件setup.py第一行代码导入setup库,其中name为打包库的.egg-info文件名descriptionversion="1.0"这说明了文件名的后缀,如果不设置后缀会默认为0.0.0ext_modules=[Extension("mymod",["mymod.c"])]其中mymode是对应的模块名和模块文件名,而["mymod.c"]我s源码编译成库文件可以是多个文件,这里是一个python列表数组。fromdistutils.coreimport*setup(name="mymod",#package文件名库描述文件名version="1.0",ext_modules=[Extension("mymod",["mymod.c"])])最后运行命令pythonsetup.pyinstall,编译成功。在当前路径下会生成一个build目录,里面包含编译后的内容。应该是因为运行了install命令,所以不仅编译了,还安装了。扩展库安装路径:F:Python-3.7.0Libsite-packages7扩展库调用测试扩展库编译跟进。当我们编写了一段python代码进行测试后,就完成了我们的第一个python扩展库程序。