Skip to content Skip to sidebar Skip to footer

Controlling C++ Output From Python Script

I have a bit of an issue here. I have a Python script which calls binaries compiled from C++. The Python script has its own set of outputs (to standard out and error), which are

Solution 1:

One way to do this is:

  • Duplicate in python the file descriptors for stdout and stderr using os.dup.
  • Redirect the original stdout and stderr using reopen (from C's stdio) to write to a file of your choice.

Note: reopen isn't available directly from python, but you should be able to call it as in the example below or using any other wrapper available.

After this is done:

  • Every write to cout and cerr in C++ will write to the output files.
  • Every print statement in python will write to the output files.

However, since the original descriptors are duplicated, you can still (see example below):

  • Print to the original stdout/stderr using sdout.write and stdout.err
  • Use logging methods after configuring properly the stream parameter

The following code uses instant library to test real C++ code that is wrapped into python using SWIG and that should be similar to the library that you have:

import sys, os
import logging
from instant import inline

print'This is printed from python to stdout'
stdout = os.fdopen(os.dup(sys.stdout.fileno()), 'w')
stderr = os.fdopen(os.dup(sys.stderr.fileno()), 'w')

logging.basicConfig(stream=stderr, level=logging.DEBUG)

redirect = inline("""                                                                                                                    
void redirect(void) {                                                                                                                    
    freopen("my_stdout.txt", "w", stdout);                                                                                               
    freopen("my_stderr.txt", "w", stderr);                                                                                               
}                                                                                                                                        
""")
redirect()

cout = inline("""                                                                                                                        
void cout(void) {                                                                                                                        
    std::cout << "This is written from C++ to my_stdout.txt" << std::endl;                                                               
    std::cerr << "This is written from C++ to my_stderr.txt" << std::endl;                                                               
}                                                                                                                                        
""")
cout()

print'This is written from python to my_stdout.txt'

stdout.write('This is printed from python to stdout\n')
stderr.write('This is printed from python to stderr\n')
logging.info('This is printed to stderr from python using logging')

The output for this example is:

$ python test.py
This is printed from python to stdout
This is printed from python to stdout
This is printed from python to stderr
INFO:root:This is printed to stderr from python using logging
$ cat my_stdout.txt 
This is written from C++ to my_stdout.txt
This is written from python to my_stdout.txt
$ cat my_stderr.txt 
This is written from C++ to my_stderr.txt

Note: First time the code is executed, you might get gcc compilation messages (I've removed them to make the example clearer).

Solution 2:

Are you using subprocess to compile the C++? If so, you can set where stderr and stdout go:

nowhere = StringIO()
subprocess.call("exit 1", shell=True, stdout=nowhere, stderr=nowhere)

Post a Comment for "Controlling C++ Output From Python Script"