前面几篇文章介绍了:python程序如何调C DLL,如何使用VS2015调试python程序和调试被python调用的C DLL程序。本文则反过来探索,在C++程序中如何调python脚本。大致有两种方法:一是使用“system()”函数启动python解释器,在外部执行python脚本;二是将python解释器嵌入C++程序中,直接执行嵌入的python代码。
一、system()函数
这个方法的优点是:简单实用。它需要做的是如下几点:
1)安装python,并设置“环境变量”。
我安装的是WinPython,内嵌的是“python3.5.3”版本。这个安装过程前面已经介绍过了。
环境变量的设置主要有两个:PYTHONHOME和PYTHONPATH
PYTHONHOME="C:\Python\WinPython353\python-3.5.3"
PYTHONPAT="C:\Python\WinPython353\python-3.5.3\lib"
Path=...;%PYTHONHOME%;%PYTHONPAT%
如上图所示命令:第一条即可确认“python的安装和环境变量设置”是否正确;第二三条主要是测试PYTHONHOME和PYTHONPATH是否输入正确;最后一条用于查看所有的环境变量。
2,新建一个名为“C2Py”的Win32 console工程,并写入如下代码:
// C2Py.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
using namespace std;
int main()
{
cout << "-------- Python application begin --------\n" << endl;
system("python start.py");
cout << "\n-------- Python application end --------\n" << endl;
system("pause");
return 0;
}
3,写一个简单的python脚本,名为“start.py”
#start.py
def main():
print("Hello, Python")
if __name__ == '__main__':
main()
这个方法的缺点也很明显:
1)目标机器必须也安装了python,其正确设置了“环境变量”;
2)C++程序不能和python程序直接交互(但可以使用文件作为中介交互信息)。
二、将python解释器嵌入C++
这个方法主要参考python的官方文档:https://docs.python.org/3.5/extending/embedding.html
需要说明的是:官方文档对此的描述并不详细,特别是对VS IDE的配置,没有任何说明。仅仅参考官方文档,要把它运行起来,还是要踩不少的坑。此外,我用的是python3.5,下面具体的代码根据python的版本不同稍有差别,这个在官方文档里已体现出来了。
1,“环境变量”设置
这个跟上一个方法中的设置过程是一样的,之所以又拿出来说,是因为我刚开始的时候,安装官方文档,写好了C++代码,一运行就会出现如下错误:
Fatal Python error: Py_Initialize: unable to load the file system codec
LookupError: no codec search functions registered: can't find encoding
在google上搜了不少文章,都说是“环境变量”配置的不对,但按照他们的方法重新设置后,还是不行。最后,看到一个哥们说“你设置完环境变量,试着重启一下电脑再看”。果然,重启后就好了。汗!!!
2,新建Win32 console工程 —— “C2Python”
// C2Python.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
int main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_Finalize();
PyMem_RawFree(program);
system("pause");
return 0;
}
3,设置工程属性
从前面的代码可知:
#include
这个头文件就在python安装目录下的include文件夹中,所以要将该文件夹设置为“C2Python”工程的“包含目录”。
除此之外,一运行,链接器会报错“can not find python35.lib”。而这个lib文件就在python安装目录下的libs文件夹中,因此也要将它设置为工程的“库目录”。
工程属性的设置如下:
看粗体字。
4,运行
做完上述步骤后,在Release模式下生成“C2Python.exe”,运行结果如下:
5,debug模式
上面特别强调了,在Release模式下运行,是因为默认的python发行版本中,“libs目录”下只有“python35.lib”,没有“python35_d.lib”。
如果想在debug下运行,一种方式是自己用python源码编译一个debug版本的“python35_d.lib”。下面这个帖子给出了编译方法:
https://stackoverflow.com/questions/17028576/using-python-3-3-in-c-python33-d-lib-not-found
另一种方法是:在包含“
#ifdef _DEBUG
#undef _DEBUG
#include
#define _DEBUG
#else
#include
#endif
//#include
附:后面将继续介绍“c++与python之间互调时的参数和返回值的转换”。
VS 支持C++的python扩展:
https://docs.microsoft.com/zh-cn/visualstudio/python/cpp-and-python