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 easily disable-able. The C++ binaries have their own set of outputs (to standard out and error, among others) as well; the source can be altered, but I am not the original author. This is an issue because I do not want the C++ output in my final program, and I also don't want future users to need to edit the C++ source.
What I'd like to be able to do is have some Python method which will catch the C++ code's output that is sent to standard out or error. Is this possible? If so, could someone point me in the right direction?
Thank you!!
One way to do this is:
stdout
and stderr
using os.dup
. 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:
cout
and cerr
in C++ will write to the output files. print
statement in python will write to the output files. However, since the original descriptors are duplicated, you can still (see example below):
stdout
/ stderr
using sdout.write
and stdout.err
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).
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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.