学了一段时间的python,对C++调用Python的程序也有了几分兴趣,在网上找寻方法的时候,也遇到了一些问题,这里就将自己试过并成功的方法加以说明。
首先是对于环境的配置,这里我个人使用的是Windows系统加VS2008和Python2.7.5。当你正常安装了python后,在Windows系统下,会在System32文件夹下会多出一个.dll文件,由于本人使用的是python2.7.5,所以多出来的是python27.dll。但是这还不够,我们还需要一个python27_d.dll文件。这个文件在你的python安装目录下是不存在的,需要我们自行编译生成或者上网下载他人编译好的。
这里先不说如何编译从而生成我们所需的文件,先将python安装目录下的include文件夹下的文件全部复制到VS2008安装目录下的VC的目录下的include文件夹内,如果按以上方式复制文件的话,在引用头文件时使用#include<python.h>便可,当然如果你想出于方便管理的角度来讲,也可以在VC的include文件下新建一个文件,譬如新建一个名为“python”的文件夹用来存放与python相关的头文件,这样在引用头文件时使用#include<python/python.h>也可。
这里使用的是VS2008,所以复制到对应安装目录下的include便可;之后将python安装目录下的libs文件夹下文件复制到VC对应的lib文件夹下。
现在我们来说一说如何编译生成python27_d.dll以及接下来还需要的重要文件python27_d.lib两个文件, 我们可以从python.org上下载python_2.7.5.tgz以获得python的源码包,解压后会有这样一个文件夹PCbuild。
打开里面的pcbuild.sln,我们会打开整个python的工程,打开工程的属性中注意以下两个红线处的设置。
设置好后,进入下一步,这里只将python与pythoncore两项勾选,其他全部取消勾选。
在完成这步以后,我们先单独编译make_buildinfo与make_versioninfo两项。
在这一步完成之后,对整个工程进行编译便可。这里存在release和debug两种版本,其生成的.dll和.lib文件会有不同,这里我用的debug,对于使用貌似没什么问题,具体的区别还望有了解的大神解答了。
这里找到我们需要的文件,备份一下吧,以后会经常用到。这里是我编译生成的文件(点击链接下载),有需要可以下载。
我们先从简单的开始,用C++调用Python的函数吧,先是无参的函数调用,我的hello.py下的代码为
def Hello():
print "Hello,Python!"
这里我在看他人的博客时,他使用的是test.py,但是在运行时会出现错误,有人留言说VC中不能用“test”文件名,具体原因不清楚,希望有了解的大神能不吝赐教了。
C++部分的代码完整如下:
#include<python/python.h>
int main()
{
Py_Initialize();//--1--
PyObject * pModule = NULL;//--2--
PyObject * pFunc = NULL;
PyObject * pArg = NULL;
pModule = PyImport_ImportModule("demo");//--3--
pFunc = PyObject_GetAttrString(pModule, "Hello");//--4--
PyEval_CallObject(pFunc, NULL);//--5--
Py_Finalize();//--6--
system("pause");
return 0;
}
① :在使用python的函数之前,要先调用Py_Initialize(),算作是初始化,启动python解释器。
② :在C++中,python的对象均是PyObject类型,常用PyObject *,以上是声明在几个在python要使用的变量。
③ :PyImport_ImportModule()中间的参数值就是你要使用的脚本文件的名字这里不需要加上文件的后缀名。
④ :PyObject_GetAttrString()通过该方法来获得你需要的函数。
⑤ :PyEval_CallObject()来执行你想使用的脚本文件中的函数,这里我们使用的Hello函数没有参数,所以使用NULL作为PyEval_CallObject()的参数便可,下一节会讲到带参数的python函数的引用。
⑥ :对应Py_Finalize(),关闭python解释器,与Py_Initialize()相对应出现。
以上各个函数在python的帮助文档中均有说明,大家想进一步了解的话可以进行查阅。