W gruncie rzeczy próbuję napisać interfejs konsoli z wejściowym i wyjściowym dla wbudowanego skryptu python. Postępując zgodnie z instrukcjami here, udało mi się uchwycić stdout:Asynchronicznie przekierować stdout/stdin z osadzonego python na 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();
Problem polega na tym, że ja tylko odbierać stdout po skrypt zakończy działanie, natomiast idealnie do konsoli stdoutstring byłoby zaktualizować jako skrypt Pythona aktualizuje go. Czy jest jakiś sposób na zrobienie tego?
Co powinienem zrobić, przechwytując stdin?
Jeśli to pomaga, pracuję z kompilatorem, który akceptuje Objective-C. Mam również dostępne biblioteki boost.
Wymyśliłem stdout część pytania. Dla potomności, to działa:
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();
nadal występują problemy z stdin ...
PS. dzięki za twoje rozwiązania powyżej, znalazłem je bardzo pomocne! – Dave