2011-10-28 29 views
12

Tôi chủ yếu cố gắng viết giao diện điều khiển với đầu vào và đầu ra cho tập lệnh python được nhúng. Theo các hướng dẫn here, tôi đã có thể nắm bắt stdout:Chuyển hướng không đồng bộ stdout/stdin từ python được nhúng sang 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(); 

Vấn đề ở đây là tôi chỉ nhận được những stdout sau kịch bản đã chạy xong, trong khi lý tưởng cho một giao diện điều khiển các stdoutstring sẽ cập nhật như python script cập nhật nó. Có cách nào để làm việc này không?

Ngoài ra, làm thế nào tôi sẽ đi về chụp stdin?

Nếu có ích, tôi đang làm việc với trình biên dịch chấp nhận Mục tiêu-C. Tôi cũng có sẵn thư viện tăng cường.


Tôi đã tìm ra phần stdout của câu hỏi. Cho hậu thế, công trình này:

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(); 

Vẫn gặp sự cố với thiết bị nhập chuẩn ...

Trả lời

1

Để xử lý tất cả các đầu vào có sẵn bên trong Python tôi khuyên bạn nên module fileinput.

Nếu bạn muốn xử lý đầu vào dưới dạng lệnh dòng-by-line, (chẳng hạn như trong một thông dịch viên tương tác), bạn có thể tìm thấy hàm python raw_input hữu ích.

Để chuyển hướng stdin sử dụng một lớp helper tương tự như những người bạn đã sử dụng ở trên, chức năng ghi đè lên là readline, không đọc. Xem this link để biết thêm thông tin về điều đó (và cả raw_input).

Hope this helps, Supertwang

+0

PS. cảm ơn các giải pháp của bạn ở trên, tôi thấy chúng khá hữu ích! – Dave

0

Nếu bạn gắn bó với cách tiếp cận bạn nêu, kế thừa lớp học của bạn từ io.IOBase có lẽ là một ý tưởng tốt.

1

Cách dễ nhất tôi tìm thấy cho đến nay để làm điều này là như sau:

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); 

bạn có thể thử nghiệm nó với:

# for test 
PyRun_SimpleString("print sys.stdin.readline()"); 
Các vấn đề liên quan