如何在C ++代码中捕获Python 3 stdout

时间:2017-10-08 14:58:01

标签: python-3.x python-c-api

old question中关于如何在C ++代码中捕获python stdout,there is a good answer并且它有效 - 但仅限于Python 2。

我想在Python 3中使用类似的东西。任何人都可以帮助我吗?

更新

我正在使用的代码如下。它来自上面引用的Mark答案,唯一的变化是使用301代替PyBytes_AsStringcited in documentation

PyString_AsString

我使用Python 3库构建它:

#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; }

,输出为:

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

如果有人需要有关该问题的更多信息,请告诉我,我会在此处提供。

1 个答案:

答案 0 :(得分:0)

您的问题是.value不是bytes对象,而是string(即Python2 unicode)对象。因此PyBytes_AsString失败。我们可以使用bytes将其转换为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));

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