[C++-sig] Redirecting stdout for B.P extensions?
Hubert.Holin at meteo.fr
Fri Sep 16 12:34:59 CEST 2005
Somewhere in the E.U., le 16/09/2005
In article <1126798273.31444.9.camel at localhost.localdomain>,
Jonathan Brandmeyer <jbrandmeyer at earthlink.net> wrote:
> On Wed, 2005-09-14 at 19:06 -0700, Ralf W. Grosse-Kunstleve wrote:
> > --- Jonathan Brandmeyer <jbrandmeyer at earthlink.net> wrote:
> > > You can write a custom streambuf that dumps its data via
> > > PyFile_WriteString() to sys.stderr, and redirect std::cerr to an
> > > instance of your custom streambuf. This way, redirection of sys.stderr
> > > from within Python will have the intended effect on std::cerr.
> > Very interesting. I'd like to add some fragments of production code that
> > show
> > how to use the Python C API to write to sys.stdout (or any other Python
> > object
> > with write() and flush() methods). See below. The "python_out" class is
> > wrapped
> > with Boost.Python and instantiated with sys.stdout as the argument.
> > Question: how can I redirect std::cout and std::cerr to use a custom
> > streambuf
> > object? Can I simply write std::cout = my_custom_streambuf_instance? That
> > would
> > be exciting.
> std::streambuf* old = std::cout.rdbuf( &my_custom_streambuf_instance);
> Here is a start that adapts some of your code to suit.
> After importing sbuf_test, the program will crash on shutdown when cout
> and cerr's destructors try to flush the Python stream that has already
> been finalized. Perhaps this would be a good point to add a PyFinalize
> hook that restores the streambufs?
[SNIP extremely useful code]
Thank you (Jonathan Brandmeyer, Ralf W. Grosse-Kunstleve and
Pierre Barbier de Reuille) for your suggestions and code (which has the
added benefit of appearing to be perfectly portable). I will try to use
them as the basis of my code.
To attain the goal of transparency (to third-party code, even if
the third party happens to bee one of the first two :-) ), I am
thinking to allocate a global custom streambuf in an extension (and
bring it down explicitly later) to perform the redirection. Must I
expose that object to Python to insure it will still be alive and active
when another extension is called?
Are there any actual guaranties about inter-extension
non-Python-exposed, C++ object visibility? Or just about the lifetime of
(C++) objects allocated in extensions (exposed to Python or not)?
More information about the Cplusplus-sig