VS2015 C++程序调Pyhon脚本

    前面几篇文章介绍了: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的前提。要确认“python的安装和环境变量设置”是否正确,在需要打开“cmd.exe”,再输入“python”即可。

VS2015 C++程序调Pyhon脚本_第1张图片


    如上图所示命令:第一条即可确认“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;
}

编译生成“C2Py.exe”文件。


3,写一个简单的python脚本,名为“start.py”

#start.py

def main():
    print("Hello, Python")

if __name__ == '__main__':
    main()

4,将 “C2Py.exe”文件和“start.py”两个文件放在同一个目录下,直接运行“C2Py.exe”,即可看到从C++启动python解释器执行python程序。如下:

VS2015 C++程序调Pyhon脚本_第2张图片


这个方法的缺点也很明显:

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文件夹中,因此也要将它设置为工程的“库目录”。

    工程属性的设置如下:

VS2015 C++程序调Pyhon脚本_第3张图片


    看粗体字。


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


    另一种方法是:在包含“”文件的地方,临时屏蔽“_debug”宏,如下:

#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

你可能感兴趣的:(C/C++,Python)