在C++应用程序中嵌入Python解释器时,调用官方提供的接口“PyRun_SimpleString”只能获取到脚本执行是否成功,而无法获取标准输出和标准出错,之前曾尝试过使用将重定向到文件的方式,但效果并不理想,在调用Pywinauto时,出现了文件访问异常,代码及异常如下所示:
PyRun_SimpleString("import sysnfile = open('out.txt','w')nsys.stdout = filensys.stderr = file");
......
PyRun_SimpleString("file.close()");
在解决该问题的过程中,发现Python解释器执行Py脚本的标准输出和标准出错会打印在控制台上,为此尝试在C++应用程序中将标准输出重定向到文件中,经过测试发现,cout/printf可以重定向到文件中,但执行python脚本时,则会发生异常,源码及异常如下所示:
FILE* stream;
freopen_s(&stream, "file.txt", "w", stdout);
为解决重定向的问题,通过查阅官方资料,反复测试调试,终于找到了新的解决方案,依然使用重定向的方式,但不再重定向到文件中,而是重定向内存中,使用PyObject_GetAttrString获取,代码如下:
#include
#include "Python.h"
int main()
{
std::cout << "Hello World!n";
std::string stdOutErr =
"import sysn
class CatchOutErr:n
def __init__(self):n
self.value = ''n
def write(self, txt):n
self.value += txtn
catchOutErr = CatchOutErr()n
sys.stdout = catchOutErrn
sys.stderr = catchOutErrn
"; //this is python code to redirect stdouts/stderr
Py_Initialize();
PyObject* pModule = Pyimport_AddModule("__main__"); //create main module
PyRun_SimpleString(stdOutErr.c_str()); //invoke code to redirect
PyRun_SimpleString("from pywinauto import application"); //this is ok stdout
PyRun_SimpleString("app = application.Application()"); //this is ok stdout
PyRun_SimpleString("app.start("C:\Program Files\yjkSoft\YJKS_3_1\yjks.exe")"); //this is ok stdout
PyRun_SimpleString("1+a"); //this creates an error
PyObject* catcher = PyObject_GetAttrString(pModule, "catchOutErr"); //get our catchOutErr created above
PyErr_Print(); //make python print any errors
PyObject* output = PyObject_GetAttrString(catcher, "value"); //get the stdout and stderr from our catchOutErr object
printf("Here's the output:n %s", _PyUnicode_AsString(output)); //it's not in our C++ portion
Py_Finalize();
}



