2011-10-28 121 views
12

我本质上是试图编写一个控制台接口输入和输出嵌入式的Python脚本。继说明here,我能捕捉到标准输出:将stdout/stdin从嵌入式python异步重定向到C++?

Py_Initialize(); 
PyRun_SimpleString("\ 
class StdoutCatcher:\n\ 
    def __init__(self):\n\ 
     self.data = ''\n\ 
    def write(self, stuff):\n\ 
     self.data = self.data + stuff\n\ 
import sys\n\ 
sys.stdout = StdoutCatcher()"); 

PyRun_SimpleString("some script"); 

PyObject *sysmodule; 
PyObject *pystdout; 
PyObject *pystdoutdata;  
char *string; 
sysmodule = PyImport_ImportModule("sys"); 
pystdout = PyObject_GetAttrString(sysmodule, "stdout"); 
pystdoutdata = PyObject_GetAttrString(pystdout, "data");  
stdoutstring = PyString_AsString(pystdoutdata); 

Py_Finalize(); 

这样做的问题是,我只收到标准输出脚本运行完毕后,而理想的控制台stdoutstring将作为更新python脚本更新它。有没有办法做到这一点?

另外,我怎么会去捕捉标准输入?

如果有帮助,我有一个接受的Objective-C编译器的工作。我也有可用的增强库。


我已经想出了问题的标准输出部分。对于后人,这个工程:

static PyObject* 
redirection_stdoutredirect(PyObject *self, PyObject *args) 
{ 
    const char *string; 
    if(!PyArg_ParseTuple(args, "s", &string)) 
     return NULL; 
    //pass string onto somewhere 
    Py_INCREF(Py_None); 
    return Py_None; 
} 

static PyMethodDef RedirectionMethods[] = { 
    {"stdoutredirect", redirection_stdoutredirect, METH_VARARGS, 
     "stdout redirection helper"}, 
    {NULL, NULL, 0, NULL} 
}; 

//in main... 
    Py_Initialize(); 
    Py_InitModule("redirection", RedirectionMethods); 
    PyRun_SimpleString("\ 
import redirection\n\ 
import sys\n\ 
class StdoutCatcher:\n\ 
    def write(self, stuff):\n\ 
     redirection.stdoutredirect(stuff)\n\ 
sys.stdout = StdoutCatcher()"); 

    PyRun_SimpleString("some script"); 

    Py_Finalize(); 

还是有问题:标准输入...

回答

1

处理所有可用的输入Python的里面我推荐的fileinput模块。

如果您想要将输入作为逐行命令处理(例如在交互式解释器中),您可能会发现python函数raw_input有用。

重定向使用类似的辅助类标准输入如您在上面所使用的那些,覆盖功能的readline,不阅读。有关(和raw_input)的更多信息,请参阅this link

希望这有助于 Supertwang

+0

PS:

PyObject *sys = PyImport_ImportModule("sys"); PyObject* io_stdout = PyFile_FromFile(stdout, "stdout", "a", nullptr); PyObject_SetAttrString(sys, "stdout", io_stdout); PyObject* io_stderr = PyFile_FromFile(stderr, "stderr", "a", nullptr); PyObject_SetAttrString(sys, "stderr", io_stderr); PyObject* io_stdin = PyFile_FromFile(stdin, "stdin", "r", nullptr); PyObject_SetAttrString(sys, "stdin", io_stdin); 

你可以对其进行测试。感谢您的解决方案,我发现它们非常有帮助! – Dave

0

如果你坚持你所概述的方法,继承了io.IOBase类可能是一个好主意。

1

我迄今发现这样做是如下最简单的方法:

# for test 
PyRun_SimpleString("print sys.stdin.readline()");