如何在C ++代码中捕获Python 3 stdout [英] How to catch Python 3 stdout in C++ code

查看:167
本文介绍了如何在C ++代码中捕获Python 3 stdout的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在有关如何捕捉的老问题中C ++代码中的python stdout,有一个很好的答案,并且有效-但仅适用于Python 2.

In an old question about how to catch python stdout in C++ code, there is a good answer and it works - but only in Python 2.

我想在Python 3中使用类似的东西.有人可以在这里帮助我吗?

I would like to use something like that with Python 3. Anyone could help me here?

更新

我正在使用的代码如下.它是从上面引用的Mark答案移植而来的,唯一的变化是使用了PyBytes_AsString而不是PyString_AsString,如 .

The code I am using is below. It was ported from Mark answer cited above, the only change was the use of PyBytes_AsString instead of PyString_AsString, as cited in documentation.

#include <Python.h>
#include <string>

int main(int argc, char** argv)
{
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("print(1+1)"); //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", PyBytes_AsString(output)); //it's not in our C++ portion

Py_Finalize();


return 0;
}

我使用Python 3库进行构建:

I build it using Python 3 library:

g++ -I/usr/include/python3.6m -Wall -Werror -fpic code.cpp -lpython3.6m

,输出为:

Here's the output: (null)

Here's the output: (null)

如果有人需要有关此问题的更多信息,请告诉我,我将尝试在此处提供.

If someone needs more information about the question, please let me know and I will try provide here.

推荐答案

您的问题是.value不是bytes对象,而是string(即Python2 unicode)对象.因此PyBytes_AsString失败.我们可以使用PyUnicode_AsEncodedString将其转换为bytes对象.

Your issue is that .value isn't a bytes object, it is a string (i.e. Python2 unicode) object. Therefore PyBytes_AsString fails. We can convert it to a bytes object with PyUnicode_AsEncodedString.

PyObject *output = PyObject_GetAttrString(catcher,"value"); //get the stdout and stderr from our catchOutErr
PyObject* encoded = PyUnicode_AsEncodedString(output,"utf-8","strict");
printf("Here's the output:\n %s", PyBytes_AsString(encoded));

请注意,您应该针对NULL检查这些结果PyObject*,以查看是否发生了错误.

Note that you should be checking these result PyObject* against NULL to see if an error has occurred.

这篇关于如何在C ++代码中捕获Python 3 stdout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆