Redirection of stdout from a SWIG-wrapped C++ class to a non-file python object
I'm trying to redirect the output from a SWIG-wrapped C module to a python class. The SWIG caller is a python class which already has sys.stdout overwritten in the following way:
with _redirect_streams():
my_C_function(sys.stdout)
try:
out_s = sys.stdout.getvalue()
except AttributeError:
out_s = ""
try:
err_s = sys.stderr.getvalue()
except AttributeError:
err_s = ""
class _redirect_streams(object):
def __enter__(self):
self._orig_stdout = sys.stdout
self._orig_stderr = sys.stderr
sys.stdout = StringIO()
sys.stderr = StringIO()
def __exit__(self, exc_type, exc_val, exc_tb):
sys.stdout = self._orig_stdout
sys.stderr = self._orig_stderr
In SWIG, I am able to redirect all the printf to go to a file handle FILE* fh
that I pass from python.
It works fine if I call my C function passing sys.__stdout__
(real file object) but if I pass sys.stdout
after it's been overwritten it's no longer a python file object (StringIO) and the C file is not able to print to that.
What is the best approach in that situation ?
Is there a way to capture the standard output in python while开发者_如何学C still passing a file-type handle to the C function ?
Edit: Actually I oversimplified a little bit, in my code the my_C_function
is still a python function which prints out on stdout while calling the SWIG-wrapper C function which itself print to the given file handle.
Thanks, Herve
I can only offer you an approach.
1. Use os.pipe() to create a fd pair
2. pass the "write" pipe down to your C
3. override "stdout" with that pipe (in C-land)
4. Now "C" stdout is going to appear in the "read" side of that os.pipe()
5. Back in python-land, read out of the pipe and write into Python's stdout.
...Probably there's a simpler approach...
精彩评论