[C++-sig] Redirecting stdout for B.P extensions?

Hubert Holin Hubert.Holin at meteo.fr
Fri Sep 16 12:34:59 CEST 2005


Somewhere in the E.U., le 16/09/2005

   Bonjour

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)?

   Merci

         Hubert Holin




More information about the Cplusplus-sig mailing list