Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > python sys.stdout and C++ iostreams::cout

Reply
Thread Tools

python sys.stdout and C++ iostreams::cout

 
 
Utpal Sarkar
Guest
Posts: n/a
 
      01-17-2013
Hi,

I was assuming that sys.stdout would be referencing the same physical stream as iostreams::cout running in the same process, but this doesn't seem to be the case.
The following code, which makes a call to a C++ function with a python wrapper called "write", that writes to cout:

from cStringIO import StringIO
import sys
orig_stdout = sys.stdout
sys.stdout = stringout = StringIO()
write("cout") # wrapped C++ function that writes to cout
print "-" * 40
print "stdout"
sys.stdout = orig_stdout
print stringout.getvalue()

immediately writes "cout" to the console, then the separator "---...", and finally, as the return value of stringout.getvalue(), the string "stdout".
My intention was to capture in stringout also the string written to cout from C++.
Does anyone know what is going on, and if so, how I can capture what is written to cout in a python string?

Thanks in advance.
 
Reply With Quote
 
 
 
 
Nobody
Guest
Posts: n/a
 
      01-17-2013
On Thu, 17 Jan 2013 07:02:24 -0800, Utpal Sarkar wrote:

> I was assuming that sys.stdout would be referencing the same physical
> stream as iostreams::cout running in the same process, but this doesn't
> seem to be the case.


At startup, it refers to the same FILE* as C's stdout. This initially
shares a buffer with C++'s std::cout, but that can be changed via
std::ios_base::sync_with_stdio().

However ...

> The following code, which makes a call to a C++
> function with a python wrapper called "write", that writes to cout:
>
> from cStringIO import StringIO
> import sys
> orig_stdout = sys.stdout
> sys.stdout = stringout = StringIO()
> write("cout") # wrapped C++ function that writes to cout print "-" * 40
> print "stdout"
> sys.stdout = orig_stdout
> print stringout.getvalue()


This code changes sys.stdout so that it refers to something other than C's
stdout. C's stdout is still the same FILE*, C++'s std::count is still the
same std:stream, and the synchronisation between the two hasn't changed.

> immediately writes "cout" to the console, then the separator "---...", and
> finally, as the return value of stringout.getvalue(), the string "stdout".
> My intention was to capture in stringout also the string written to cout
> from C++. Does anyone know what is going on, and if so, how I can capture
> what is written to cout in a python string?


Changing sys.stdout doesn't (and cannot) have any effect upon how C or C++
code behaves. sys.stdout is just a Python variable.

If you want to capture output from C or C++ code, you'll have to do so via
other means, e.g. freopen() or dup2().

 
Reply With Quote
 
 
 
 
Chris Angelico
Guest
Posts: n/a
 
      01-17-2013
On Fri, Jan 18, 2013 at 2:02 AM, Utpal Sarkar <(E-Mail Removed)> wrote:
> I was assuming that sys.stdout would be referencing the same physical stream as iostreams::cout running in the same process, but this doesn't seem to be the case.


That's more-or-less true, but there will likely be separate buffering,
so even without redirection you might see some oddities. But the
problem with your code is that you're not actually redirecting stdout
in any way; you're catching, at a fairly high level, everything that
Python would otherwise have sent there.

Is there any way that you can get the C++ code to offer a way to
redirect its output? Otherwise, you're going to have to fiddle around
with the usual mess of I/O redirection (with dup2), and you can only
send it to what the OS sees as a file (so, no StringIO buffer). So to
achieve your goal, you may need either a temporary physical file, or
some sort of pipe (and worry about reading from it before it fills up,
etc, etc). There may be alternatives, but in any case, the easiest way
is going to be with some assistance from the C++ function.

ChrisA
 
Reply With Quote
 
Utpal Sarkar
Guest
Posts: n/a
 
      01-17-2013
Thanks a lot Chris and Nobody! I'll have a look at dup2 for a start.

> > I was assuming that sys.stdout would be referencing the same physical stream as iostreams::cout running in the same process, but this doesn't seem to be the case.

>
>
>
> That's more-or-less true, but there will likely be separate buffering,
>
> so even without redirection you might see some oddities. But the
>
> problem with your code is that you're not actually redirecting stdout
>
> in any way; you're catching, at a fairly high level, everything that
>
> Python would otherwise have sent there.
>
>
>
> Is there any way that you can get the C++ code to offer a way to
>
> redirect its output? Otherwise, you're going to have to fiddle around
>
> with the usual mess of I/O redirection (with dup2), and you can only
>
> send it to what the OS sees as a file (so, no StringIO buffer). So to
>
> achieve your goal, you may need either a temporary physical file, or
>
> some sort of pipe (and worry about reading from it before it fills up,
>
> etc, etc). There may be alternatives, but in any case, the easiest way
>
> is going to be with some assistance from the C++ function.
>
>
>
> ChrisA


 
Reply With Quote
 
Utpal Sarkar
Guest
Posts: n/a
 
      01-17-2013
Thanks a lot Chris and Nobody! I'll have a look at dup2 for a start.

> > I was assuming that sys.stdout would be referencing the same physical stream as iostreams::cout running in the same process, but this doesn't seem to be the case.

>
>
>
> That's more-or-less true, but there will likely be separate buffering,
>
> so even without redirection you might see some oddities. But the
>
> problem with your code is that you're not actually redirecting stdout
>
> in any way; you're catching, at a fairly high level, everything that
>
> Python would otherwise have sent there.
>
>
>
> Is there any way that you can get the C++ code to offer a way to
>
> redirect its output? Otherwise, you're going to have to fiddle around
>
> with the usual mess of I/O redirection (with dup2), and you can only
>
> send it to what the OS sees as a file (so, no StringIO buffer). So to
>
> achieve your goal, you may need either a temporary physical file, or
>
> some sort of pipe (and worry about reading from it before it fills up,
>
> etc, etc). There may be alternatives, but in any case, the easiest way
>
> is going to be with some assistance from the C++ function.
>
>
>
> ChrisA


 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      01-17-2013
On Fri, Jan 18, 2013 at 2:51 AM, Utpal Sarkar <(E-Mail Removed)> wrote:
> Thanks a lot Chris and Nobody! I'll have a look at dup2 for a start.


Okay. Look for code that redirects the standard I/O streams and then
exec()s another process (possibly after fork()ing); you're going to be
doing pretty much the same thing. Good luck, have fun. It's a LOT
messier than simply assigning to sys.stdout, unfortunately.

ChrisA
 
Reply With Quote
 
Lie Ryan
Guest
Posts: n/a
 
      01-18-2013
On 18/01/13 02:02, Utpal Sarkar wrote:
> Hi,
>
> I was assuming that sys.stdout would be referencing the same physical stream as iostreams::cout running in the same process, but this doesn't seem to be the case.
> The following code, which makes a call to a C++ function with a python wrapper called "write", that writes to cout:
>
> from cStringIO import StringIO
> import sys
> orig_stdout = sys.stdout
> sys.stdout = stringout = StringIO()
> write("cout") # wrapped C++ function that writes to cout
> print "-" * 40
> print "stdout"
> sys.stdout = orig_stdout
> print stringout.getvalue()
>
> immediately writes "cout" to the console, then the separator "---...", and finally, as the return value of stringout.getvalue(), the string "stdout".
> My intention was to capture in stringout also the string written to cout from C++.
> Does anyone know what is going on, and if so, how I can capture what is written to cout in a python string?
>
> Thanks in advance.
>


You might have a better luck if you check std::ios::rdbuf
(http://www.cplusplus.com/reference/ios/ios/rdbuf/)

Using std::ios::rdbuf() you can get the cout's streambuf, which is a
filebuf for the stdout and then use std::ios::rdbuf(streambuf*) to
replace cout's internal streambuf and replace it with your own
implementation that captures everything written using cout before
passing it back to the original streambuf.

This is essentially similar to assigning to sys.stdout in python.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: [Python-Dev] [python-committers] [RELEASED] Python 3.2 rc 1 R. David Murray Python 0 01-17-2011 02:23 PM
Re: [Python-Dev] [python-committers] [RELEASED] Python 3.2 rc 1 Senthil Kumaran Python 0 01-17-2011 10:31 AM
Re: [Python-Dev] [Python-3000] RELEASED Python 2.6a1 and 3.0a3 Martin v. L÷wis Python 0 03-01-2008 10:51 PM
Re: [Python-Dev] [Python-3000] RELEASED Python 2.6a1 and 3.0a3 Paul Moore Python 0 03-01-2008 10:39 PM
Searching comp.lang.python/python-list@python.org (was: UTF-8) skip@pobox.com Python 0 03-10-2007 02:50 PM



Advertisments