小编典典

如何在C ++代码中捕获python stdout

python

我有一个程序,在运行过程中有时需要调用python才能执行某些任务。我需要一个调用python并 捕获pythons stdout
并将其放入某个文件的函数。这是函数的声明

  pythonCallBackFunc(const char* pythonInput)

我的问题是捕获 给定命令 (pythonInput)的 所有python输出 。我没有使用python
API的经验,我不知道执行此操作的正确方法是什么。我尝试过的第一件事是使用Py_run_SimpleString重定向python的sdtout和stderr,这是我编写的代码的一些示例。

#include "boost\python.hpp"
#include <iostream>

void pythonCallBackFunc(const char* inputStr){

    PyRun_SimpleString(inputStr); 
}


int main () {
    ...
   //S0me outside functions does this
   Py_Initialize();
   PyRun_SimpleString("import sys");
   PyRun_SimpleString("old_stdout = sys.stdout");
   PyRun_SimpleString("fsock = open('python_out.log','a')");
   PyRun_SimpleString("sys.stdout = fsock");
   ...

   //my func   
   pythonCallBackFunc("print 'HAHAHAHAHA'");
   pythonCallBackFunc("result = 5");
   pythonCallBackFunc("print result");

   pythonCallBackFunc("result = 'Hello '+'World!'");
   pythonCallBackFunc("print result");

   pythonCallBackFunc("'KUKU '+'KAKA'");
   pythonCallBackFunc("5**3");

   pythonCallBackFunc("prinhghult");

   pythonCallBackFunc("execfile('stdout_close.py')");
   ...

   //Again anothers function code
   PyRun_SimpleString("sys.stdout = old_stdout");
   PyRun_SimpleString("fsock.close()");

   Py_Finalize();
   return 0;
}

有一个更好的方法吗?此外,由于某种原因,PyRun_SimpleString在获取一些数学表达式时不执行任何操作,例如PyRun_SimpleString(“
5 ** 3”)不打印任何内容(python conlsul打印结果:125)

也许很重要,我正在使用Visual Studio2008。谢谢,Alex


我根据Mark的建议进行了更改:

  #include <python.h>
  #include <string>

  using namespace std;

  void PythonPrinting(string inputStr){ 
     string stdOutErr =
    "import sys\n\
     class CatchOut:\n\
        def __init__(self):\n\
           self.value = ''\n\
        def write(self, txt):\n\
           self.value += txt\n\
     catchOut = CatchOut()\n\
     sys.stdout = catchOut\n\
     sys.stderr = catchOut\n\
    "; //this is python code to redirect stdouts/stderr

     PyObject *pModule = PyImport_AddModule("__main__"); //create main module
     PyRun_SimpleString(stdOutErr.c_str()); //invoke code to redirect

     PyRun_SimpleString(inputStr.c_str());
     PyObject *catcher = PyObject_GetAttrString(pModule,"catchOut");

     PyObject *output = PyObject_GetAttrString(catcher,"value");
     printf("Here's the output: %s\n", PyString_AsString(output)); 
     }

  int main(int argc, char** argv){
         Py_Initialize();

     PythonPrinting("print 123");
     PythonPrinting("1+5");
     PythonPrinting("result = 2");
         PythonPrinting("print result");

         Py_Finalize();
         return 0;
  }

我运行main后得到的输出:

 Here's the output: 123

 Here's the output:
 Here's the output: 
 Here's the output: 2

对我有好处,但只有一个问题,应该是

 Here's the output: 123

 Here's the output: 6

 Here's the output: 
 Here's the output: 2

我不知道为什么,但是在运行以下命令后:PythonPrinting(“ 1 +
5”),PyString_AsString(output)命令返回一个空字符串(char *)而不是6 …::(有什么我不能放松的地方吗?输出?

塞克斯(Alex)


阅读 211

收藏
2020-12-20

共1个答案

小编典典

如果我正确地阅读了您的问题,您想将stdout / stderr捕获到C 中的变量中吗?您可以通过将stdout /
stderr重定向到python变量,然后将此变量查询到C
中来实现。请不要说我没有在下面做适当的引用计数:

#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", PyString_AsString(output)); //it's not in our C++ portion

    Py_Finalize();


    return 0;

}
2020-12-20