redirect sys.stdout to C++ ?
André Jonsson
tatsujin at despammed.com
Sun Dec 29 09:10:30 EST 2002
Bengt Richter wrote:
>
> On Sat, 28 Dec 2002 19:43:21 +0100, =?ISO-8859-1?Q?Andr=E9_Jonsson?=
> <tatsujin at despammed.com> wrote:
<cutting long and _very_ informative post>
> It seems to be working. So what did I do differently from what you did?
> Maybe the fflush in logwrite?
Hm... it seems the problem is somehow related to the buffering I do in the C++
application.
I simplified your example to just echo to stdout of the C app, instead of to a file.
And surely enough it worked quite allright. So I then modified the redirection python
class in my code to handle the buffering, instead of the C++ log function (like in
your example), and that was it, now it works!!
Though I don't yet understand why the buffering in C++ could cause a newline
character to be "lost" from the not-yet-handled input string. I would guess I have a
rogue pointer somewhere...
Anyway, I'm greatly thankful for your help! It probably would've taken a lot longer
on my own... probably until I rewrote the whole shebang or something.
/André
Here's my version of the test code (all in one file):
--------------------------------------------------------------------------------------
#include <stdio.h>
#include <Python.h>
#include <string.h>
int logwrite(char *line)
{
int newline=line[strlen(line)-1]=='\n';
if(newline)
line[strlen(line)-1]='\0';
printf("logwrite(\"%s%s\")\n", line, newline?"\\n":"");
return 0;
}
static PyObject *andre_log(PyObject *self, PyObject *args)
{
char *s_line;
if (!PyArg_ParseTuple(args, "s:andrelog", &s_line))
return NULL;
Py_BEGIN_ALLOW_THREADS
logwrite(s_line);
Py_END_ALLOW_THREADS
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef andreMethods[] = {
{"andre_log", (PyCFunction)andre_log, METH_VARARGS,
"andre_log(line) writes a log message"},
{NULL, NULL, 0, NULL}
};
int main(int argc, char *argv[])
{
char *prompt = "Enter Python line: ";
char line[128];
Py_Initialize();
Py_InitModule("andreApp", andreMethods);
PyRun_SimpleString(""
"import andreApp # a module interface created by C application\n"
"class Logger:\n"
" def __init__(self):\n"
" self.buf = []\n"
" def write(self, data):\n"
" self.buf.append(data)\n"
" if data.endswith('\\n'):\n"
" andreApp.andre_log(''.join(self.buf))\n"
" self.buf = []\n"
"\n"
"import sys\n"
"sys.stdout = Logger()\n"
"#sys.stderr = Logger()\n"
"");
while(1)
{
printf(prompt);
if(fgets(line, 128, stdin) == NULL)
break;
line[strlen(line)-1]='\0'; // cut newline character
printf("main() entered: \"%s\"\n", line);
PyRun_SimpleString(line);
}
Py_Finalize();
return 0;
}
--------------------------------------------------------------------------------------
> ./pytest
Enter Python line: print '1'
main() entered: "print '1'"
logwrite("1\n")
Enter Python line: print '1'
main() entered: "print '1'"
logwrite("1\n")
The problem was that the last newline was missing...
More information about the Python-list
mailing list