Python标准输出重定向

在C++应用程序中嵌入Python解释器时,调用官方提供的接口“PyRun_SimpleString”只能获取到脚本执行是否成功,而无法获取标准输出和标准出错,之前曾尝试过使用将重定向到文件的方式,但效果并不理想,在调用Pywinauto时,出现了文件访问异常,代码及异常如下所示:

PyRun_SimpleString("import sys\nfile = open('out.txt','w')\nsys.stdout = file\nsys.stderr = file");

......
 PyRun_SimpleString("file.close()");

在解决该问题的过程中,发现Python解释器执行Py脚本的标准输出和标准出错会打印在控制台上,为此尝试在C++应用程序中将标准输出重定向到文件中,经过测试发现,cout/printf可以重定向到文件中,但执行python脚本时,则会发生异常,源码及异常如下所示:

FILE* stream;
freopen_s(&stream, "file.txt", "w", stdout);

为解决重定向的问题,通过查阅官方资料,反复测试调试,终于找到了新的解决方案,依然使用重定向的方式,但不再重定向到文件中,而是重定向内存中,使用PyObject_GetAttrString获取,代码如下:

#include <iostream>
#include "Python.h"

int main()
{
    std::cout << "Hello World!\n";
    std::string stdOutErr =
        "import sys\n\
class CatchOutErr:\n\
    def __init__(self):\n\
        self.value = ''\n\
    def write(self, txt):\n\
        self.value += txt\n\
catchOutErr = CatchOutErr()\n\
sys.stdout = catchOutErr\n\
sys.stderr = catchOutErr\n\
"; //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();
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值