Redirecting STDOUT using C calls.

Tom Gaudasinski amicus at adam.com.au
Sun Dec 30 05:42:01 EST 2007


Greetings,
    I'm trying to redirect python's stdout to another location. The 
reason for this is that I'm embedding python in an application. Now, 
originally my code was developed for Linux and that did not require 
redirection due to the fact that every X11 application can have an 
STDOUT associated with it. I then proceeded to take interest in making 
my code portable and looked at compiling it on windows, however Win32 
GUI applications are not given an STDOUT by default. One has to first 
AllocConsole() and then reassign the handles using magic tokens 
"CON(IN|OUT)$" such as freopen("CONOUT$", "w", stdout). I like to keep 
code clean and would like to stick to the C API as much as possible.
    I dived into the source and figured out two ways of doing it:

------------------------------------------------
#include <Python.h>
#include <iostream>

// Demonstrates redirection after initialisation.
int main() {
        Py_Initialize();
        FILE* afile = fopen("zig.txt", "w+");
        PySys_SetObject("stdout", PyFile_FromFile(afile, "zig.txt", 
"wb", fclose));
        // I would be using boost::python::exec, but let's stick to basics.
        PyRun_SimpleString("print(\"pytest1\")");
        Py_Finalize();
        fclose(afile);
        return 0;
}
------------------------------------------------
#include <Python.h>
#include <cstdio>
#include <iostream>

// Demonstrates redirection before initialisation.
int main() {
        FILE* afile = fopen("zig.txt", "w+");
        // All of this program's output to file.
        stdout = afile;
        Py_Initialize();
        PyRun_SimpleString("print(\"pytest2\")");
        Py_Finalize();
        fclose(afile);
        return 0;
}
------------------------------------------------

    For exemplary purposes, i've used files as the target for 
redirection, however the actual target in windows would be the FILE* 
gained from opening the "CONOUT$" virtual file. Both of these examples 
compile and work fine on linux, however I get an illegal access 
exception (a SIGSEGV equivalent i think) on Windows (XP). Why? The 
illegal access happens on the line that executed the python print() 
function. What is the cause for this and how can i fix it?
    It may also help to mention that the following *Python* code works 
in Windows:
------------------------------------------------
import sys
sys.stdout = open("CONOUT$", "w", 0)
print("foo")
------------------------------------------------
    So if this works, there must be a difference between how the inbuilt 
open() opens and assigns the pointers than how the C API does it. Any ideas?

Thank you.



More information about the Python-list mailing list