[Boost-users] (Boost.Python) How to print from C++ to the same stream as Python's 'print' does?

522 views
Skip to first unread message

Dietrich Bollmann

unread,
May 11, 2009, 12:11:56 PM5/11/09
to boost...@lists.boost.org
Hi,

I would like to print from C++ to the same stream as Python's 'print'
command does. I am using an embedded Python shell and when using
std::cout nothing is printed at all...

Currently I am using the following code:

std::ostringstream oss;
oss << "test\n";
std::string cs = oss.str();
PySys_WriteStdout(cs.c_str());

I wonder if there is an easier way to get the same result?

Thanks, Dietrich


_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Early Ehlinger

unread,
May 11, 2009, 5:17:50 PM5/11/09
to boost...@lists.boost.org
This is very old and probably largely wrong by now, but the general concept is the same.

http://www.respower.com/~earlye/programming/19991206.001.htm

Basically, you need to create a streambuf class that calls PySys_WriteStdout() inside your_streambuf_class::sync().

-- Early Ehlinger
--
Early Ehlinger

Christopher Currie

unread,
May 13, 2009, 4:11:12 AM5/13/09
to boost...@lists.boost.org
On Mon, May 11, 2009 at 2:17 PM, Early Ehlinger <ear...@gmail.com> wrote:
> Basically, you need to create a streambuf class that calls
> PySys_WriteStdout() inside your_streambuf_class::sync().
>> http://lists.boost.org/mailman/listinfo.cgi/boost-users

It's probably fairly straightforward to do this using Boost.Iostreams,
by creating a model of Sink:

include <Python.h>

#include <algorithm> // min
#include <iosfwd> // streamsize
#include <boost/iostreams/categories.hpp> // sink_tag
#include <boost/iostreams/stream.hpp> // stream
#include <boost/format.hpp> // format

class pysys_stdout_sink {
public:
typedef char char_type;
typedef boost::iostreams::sink_tag category;

std::streamsize write( const char* s, std::streamsize n ) {
// PySys_WriteStdout truncates to 1000 chars
static const std::streamsize MAXSIZE = 1000;

std::streamsize written = std::min( n, MAXSIZE );
PySys_WriteStdout( (boost::format("%%.%1%s") %
written).str().c_str(), s );

return written;
}
};

boost::iostreams::stream<pysys_stdout_sink> pysys_stdout;

int main()
{
Py_Initialize();
pysys_stdout << "Hello, Python world!\n";
}

HTH,
Christopher

Early Ehlinger

unread,
May 13, 2009, 7:19:20 AM5/13/09
to boost...@lists.boost.org
I don't know if that helps the OP, but it's certainly an improvement over mine!

Thanks.

-- Early
--
Early Ehlinger

Dietrich Bollmann

unread,
May 14, 2009, 10:35:41 AM5/14/09
to boost...@lists.boost.org
Hi Christopher and Early,

...I thought there is some standard Boost.Python stream somewhere anyway
and didn't expect this kind of solution :)

The code became longer than before (at least when calculating the
definition of the sink class also) - but much more elegant :)

Before:

std::ostringstream oss;
oss << "Hello, Python world!" << std::endl;


std::string cs = oss.str();
PySys_WriteStdout(cs.c_str());

Now:

boost::iostreams::stream<pysys_stdout_sink> pysys_stdout;

pysys_stdout.open(pysys_stdout_sink());
pysys_stdout << "Hello, Python world!" << std::endl;

(I had to add the line:
pysys_stdout.open(pysys_stdout_sink());
to make it work.)

Thank you very much for your help,

Dietrich

---
Here the code to play around with on unix/linux - maybe it is helpful
for some other person with the same problem:

mkdir -p /tmp/pysys_stdout
cd /tmp/pysys_stdout

cat > pysys_stdout.cpp <<FIN
/* pysys_stdout.cpp */

#include <python2.5/Python.h>

#include <algorithm> // min
#include <iosfwd> // streamsize
#include <boost/iostreams/categories.hpp> // sink_tag
#include <boost/iostreams/stream.hpp> // stream
#include <boost/format.hpp> // format

class pysys_stdout_sink {
public:
typedef char char_type;
typedef boost::iostreams::sink_tag category;

std::streamsize write( const char* s, std::streamsize n ) {

// PySys_WriteStdout truncates to 1000 chars
static const std::streamsize MAXSIZE = 1000;

std::streamsize written = std::min( n, MAXSIZE );
PySys_WriteStdout( (boost::format("%%.%1%s") %
written).str().c_str(), s );

return written;
}
};

boost::iostreams::stream<pysys_stdout_sink> pysys_stdout;

int main()
{
Py_Initialize();
pysys_stdout.open(pysys_stdout_sink());

pysys_stdout << "Hello, Python world!\n";
}

/* fin */
FIN

touch project-root.jam

cat > Jamfile <<FIN
# Jamfile

# Python library
lib python2.5 ;

# Build pysys_stdout example
exe pysys_stdout : pysys_stdout.cpp python2.5 ;

# fin.
FIN

ls -l

> total 8
> -rw-r--r-- 1 dietrich dietrich 131 2009-05-14 22:56 Jamfile
> -rw-r--r-- 1 dietrich dietrich 0 2009-05-14 22:56 project-root.jam
> -rw-r--r-- 1 dietrich dietrich 982 2009-05-14 22:56 pysys_stdout.cpp

bjam

> [...]

bin/gcc-4.3.3/debug/pysys_stdout

> Hello, Python world!

Reply all
Reply to author
Forward
0 new messages