未加星标

Windows下使用C++编写Python的扩展模块详细说明

字体大小 | |
[开发(python) 所属分类 开发(python) | 发布者 店小二04 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏
windows下使用C++编写python的扩展模块详细说明

一点号java交流1小时前

在Windows系统实现C++编写Python的扩展模块,折腾了很久,找到一篇文章,简单明了,给了我很大帮助。因为文章里的代码排版问题,空格丢失,让数据类型和函数名称等黏在一块,也会让刚接触C++写Python扩展模块的人产生障碍。

C++编写Python的扩展模块时总是提示Python.h找不到、提示python25_d.lib无法打开、提示Py_InitModule未定义的符号、链接时总是提示Py_InitModule等无法解析的外部符号。一路踩坑填坑,才踏平Windows上的C++编写Python的扩展模块问题。

所以在此对这篇文章进行整理,方便更多人,这篇文章确实帮到我了。

原文地址:http://blog.csdn.net/magictong/article/details/8897568

下面进行整理发布,作为对原作者的感谢,对于必要的地方会做完善修改:

环境VS2005+Python2.5.4+Windows7(32位)简介 长话短说,这里说的扩展Python功能与直接用其它语言写一个动态链接库,然后让Python来调用有点不一样(虽然本质是一样的)。而是指使用Python本身提供的API,使用C++来对Python进行功能性扩展,可以这样理解,使用更高效的语言实现一些算法计算等等需要更高执行效率的核心(或者需要与系统进行密切交互的)模块,然后让Python像调用内建标准库的方式来调用这些模块,听起来是不是很诱人?!在软件技术高速发展的今天,借助几种计算机语言来实现一个系统的例子数不胜数,目的不外乎就是性能和便利的平衡。譬如本文要讨论的使用C++来扩展Python就是Python和C++的一种巧妙的有机结合,好处不言而喻,既可以获得和C++相似的执行性能,又可以利用Python的开发灵活性。由于Python本身是使用C实现的,二者结合起来还是比较容易的。基本流程 本文不适合这样的读者――对Python完全不了解或者对C\C++完全不了解,道理你们懂的。另外就是Python里面有6种基本数据类型。你需要了解如何在C和Python之间对这些类型进行转化(这不在本文讨论范围,可以参考[1])。 言归正传,感觉前面说得太多了,实际上很简单,因此我决定少说多做。一个C++的Python扩展模块至少应该有导出函数,方法列表和初始化函数三个部分。我们用VS2005这个强大的工具开工!一般来说,你应该建一个Dll工程(至于使用exe来扩展Python可以不可以,暂时还没研究过)。下面按部就班的说明(关键说明在注释部分)。一、初始化函数//// 函数 : initPyExt// 功能 : 初始化函数// 返回值 : PyMODINIT_FUNC// 附注 : 注意,这个函数的名字不能改动。必须是init+模块名字,// 我们的模块名字是PyExt,所以函数名是initPyExt。Python在导入// 我们的PyExt模块时,会找到这个函数,并调用。这个函数实现的// 功能很简单,通过调用Py_InitModule将模块名字和映射表结合起// 来,它的意思是说PyExt这个模块使用PyExtMethods这个映射表。//PyMODINIT_FUNC initPyExt{ Py_InitModule("PyExt",PyExtMethods);}二、方法列表/* 方法列表,这个是一个C结构数组。把需要扩展的函数都映射到这个表里。 那么Python就知道你的这个扩展模块支持一些什么方法了。表的第一个字 段是方法名字,也是通过Python来调用时的名字。第二个字段是导出函数, 是真正调用的函数,也是C\C++实现的函数。第三个参数是指明Python向 C\C++函数传递参数的形式。可选的两种方式是METH_VARARGS和 METH_KEYWORDS,其中METH_VARARGS是参数传递的标准形式,它通 过Python的元组在Python解释器和C函数之间传递参数,若采用 METH_KEYWORD方式,则Python解释器和C函数之间将通过Python的字典 类型在两者之间进行参数传递。第四个字段是这个函数的说明。如果你在 python里来help这个函数,将显示这个说明。相当于在python里的函数的文档说明。*/static PyMethodDef PyExtMethods={ {"Add", Add,METH_VARARGS,"Addtwo number - edit by magictong."}, {"ExecSystem",ExecSystem,METH_VARARGS,"Execute a shell command - edit by magictong." }, {NULL,NULL, 0,NULL}};三、导出函数//// 函数 : Add// 功能 : 这是一个加法函数// 返回值 : PyObject*// 参数 : PyObject*self 这个参数我们暂时不用理会// 参数 : PyObject*args 是一个参数列表,我们需要从它解析出参数// 附注 :// 所有的导出函数都具有相同的原型:// PyObject*method(PyObject* self, PyObject* args);// PyArg_ParseTuple来完成解析参数任务。它的第一个参数是args,// 就是我们要转换的参数。第二个是格式符号。"s"代表是个string。// 从args里提取一个参数就写"s",两个的话就写"s|s",如果是一个// string,一个int,就写"s|i",有点和printf类似哦。第三个参数就是// 提取出来的参数放置的真正位置。必须传递这个参数的地址。//static PyObject* Add(PyObject* self,PyObject* args){ int x = 0 ; int y = 0; int z = 0; if(!PyArg_ParseTuple(args,"i|i", &x, &y))return NULL; z=x +y; return Py_BuildValue("i",z); /* 调用完之后我们需要返回结果。这个结果是c的type或者是我们自己定义的类型。 必须把他转换成PyObject,让python认识。这个用Py_BuildValue来完成。他 是PyArg_ParseTuple的逆过程。他的第一个参数和PyArg_ParseTuple的第二个 参数一样,是个格式化符号。第三个参数是我们需要转换的参数。Py_BuildValue 会把所有的返回只组装成一个tutple给python。 如果对应的C函数没有返回值(即返回值类型为void),则应返回一个全局的None 对象(Py_None),并将其引用计数增,如下所示: Py_INCREF(Py_None); return Py_None; */}四、再加点功能int cmd(const char* arg){ return system(arg);}static PyObject* ExecSystem(PyObject* self,PyObject* args){ const char*command; if(!PyArg_ParseTuple(args,"s", &command))return NULL; int n =cmd(command); return Py_BuildValue("i",n);}编译 开编,编译出来的PyExt.dll文件改名为PyExt.pyd放入Python的C:\Python25\DLLs目录就可以全局使用了,如果你只想某个Python的工程,放在工程的相对路径下面就可以了。使用可能的问题 里面的这些PyMODINIT_FUNC,与Python相关的宏和定义在哪里呢?定义下#include<Python.h>就可以了,但是定义了之后提示Python.h找不到还是编译不过怎么办?这说明你没有安装Python或者安装了但是没有把头文件路径引入Path环境变量,或者你把Python的include目录加入工程的附加包含目录(Additional IncludeDirectories),一般是C:\Python25\include这个目录,其中C:\Python25是Python的安装目录,按你机器的实际情况配置)。【我用的是Python3.4,结果Py_InitModule未定义的符号,总是找不到。后面重新安装了python2.7才解决这个问题】 如果提示:Error 1 fatal error LNK1104:cannot open file 'python25_d.lib' 类似这样的错误,一般可能是没有安装Python的开发版本,没关系,你使用Release编译一下,如果还不行,就把C:\Python25\libs目录加入工程的附加库目录(Additional LibraryDirectories)。

【链接】链接的时候,Py_InitModule、Py_BuildValue等这些都提示无法解析的外部符号。找了很久都没有解决,最后再StackFlow一个问题的回答里瞄到了,把项目类型改为X64,而不要用X86,然后编译就顺利通过了。

学习C++的同学注意了!!!

学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入C++学习交流群,群号码:79029676我们一起学C++!

本文开发(python)相关术语:python基础教程 python多线程 web开发工程师 软件开发工程师 软件开发流程

主题: C++WindowsPython算法ETHFU数据变量
分页:12
转载请注明
本文标题:Windows下使用C++编写Python的扩展模块详细说明
本站链接:http://www.codesec.net/view/520869.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 开发(python) | 评论(0) | 阅读(83)