Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   python sys.stdout and C++ iostreams::cout (http://www.velocityreviews.com/forums/t956609-python-sys-stdout-and-c-iostreams-cout.html)

Utpal Sarkar 01-17-2013 03:02 PM

python sys.stdout and C++ iostreams::cout
 
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.

Nobody 01-17-2013 03:35 PM

Re: python sys.stdout and C++ iostreams::cout
 
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::ostream, 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().


Chris Angelico 01-17-2013 03:42 PM

Re: python sys.stdout and C++ iostreams::cout
 
On Fri, Jan 18, 2013 at 2:02 AM, Utpal Sarkar <doetoe@gmail.com> 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

Utpal Sarkar 01-17-2013 03:51 PM

Re: python sys.stdout and C++ iostreams::cout
 
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



Utpal Sarkar 01-17-2013 03:51 PM

Re: python sys.stdout and C++ iostreams::cout
 
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



Chris Angelico 01-17-2013 03:54 PM

Re: python sys.stdout and C++ iostreams::cout
 
On Fri, Jan 18, 2013 at 2:51 AM, Utpal Sarkar <doetoe@gmail.com> 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

Lie Ryan 01-18-2013 07:21 AM

Re: python sys.stdout and C++ iostreams::cout
 
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.



All times are GMT. The time now is 05:46 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.