[C++-sig] Conversion of python files to C++ ostreams
Christopher Bruns
cmbruns at stanford.edu
Tue Apr 6 17:52:40 CEST 2010
On Sun, Apr 4, 2010 at 1:07 PM, Christopher Bruns <cmbruns at stanford.edu> wrote:
[...]
>>> // C++ API
>>> struct Foo {
>>> Foo(ostream& os);
>>> };
>>>
>>> # desired python usage
>>> foo = Foo(streambuf(sys.stdout))
Solved. Thanks everyone was politely waiting for me to find the answer
in the FAQ at http://wiki.python.org/moin/boost.python/HowTo#namedconstructors.2BAC8factories.28asPythoninitializers.29
The way to wrap constructors such as this is like so:
////////////
namespace bp = boost::python;
// I am still debating whether to use streambuf or FileObj, so
both approaches shown...
using boost_adaptbx::python::streambuf;
using mds_utils::python::oFileObj;
// Create wrapper methods for the desired constructors
static boost::shared_ptr<Foo> makeFoo1(streambuf& output) {
streambuf::ostream os(output);
return boost::shared_ptr<Foo>(new Foo(os));
}
static boost::shared_ptr<Foo> makeFoo2(oFileObj& output) {
std::ostream& os = static_cast<std::ostream&>(output);
return boost::shared_ptr<Foo>(new Foo(os));
}
// This one must be treated carefully, since it can take any
boost::python object as an argument
static boost::shared_ptr<Foo> makeFoo3(bp::object& pyfile) {
// oFileObj output(pyfile);
// return makeFoo2(output);
// or
streambuf output(pyfile);
return makeFoo1(output);
}
[...]
BOOST_PYTHON_MODULE(_test) {
bp::class_< Foo >("Foo", bp::init<>())
// First method declared here is last method to be consulted
during overload resolution
.def("__init__", bp::make_constructor(makeFoo3)) // This one
MUST be defined first!
.def(bp::init< std::ostream& >())
.def("__init__", bp::make_constructor(makeFoo1))
.def("__init__", bp::make_constructor(makeFoo2))
;
}
////////////
Now in python I can use any of the following:
foo = Foo(test_.cout) # actual C++ ostream
foo = Foo(streambuf(sys.stdout)) # boost_adaptbx wrapper
foo = Foo(oFileObje(sys.stdout)) # mds_utils wrapper
foo = Foo(sys.stdout) # seamless file object conversion, what I wanted
all along.
More information about the Cplusplus-sig
mailing list