[C++-sig] Conversion of python files to C++ ostreams
Christopher Bruns
cmbruns at stanford.edu
Sun Apr 4 22:07:11 CEST 2010
On Sat, Apr 3, 2010 at 8:54 PM, Ralf W. Grosse-Kunstleve <rwgk at yahoo.com> wrote:
>> // C++ API
>> struct Foo {
>> Foo(ostream& os);
>> };
>>
>> # desired python usage
>> foo = Foo(streambuf(sys.stdout))
>
> Did you already try the usual
>
> def(init<ostream&>((arg("os"))))
Yes. Well pretty close. Py++ code generator gives me this:
Foo_exposer.def( bp::init< std::ostream & >(( bp::arg("os") )) );
which I believe is completely equivalent. Given the following test API:
///// C++ API to wrap ////
#include <iostream>
class Foo {
public:
Foo() {std::cout << "constructor1" << std::endl;}
// The following constructor that takes an ostream& is the tricky part
explicit Foo(std::ostream& os) {os << "constructor2" << std::endl;}
// These say_hello member functions can be wrapped using current technology
void say_hello_fileobj(std::ostream& os) {os << "hello fileobj" <<
std::endl;}
void say_hello_streambuf(std::ostream& os) {os << "hello
streambuf" << std::endl;}
};
////////////////////////
I can wrap the say_hello_streambuf() member function with wrapper
functions like these:
namespace bp = boost::python;
using boost_adaptbx::python::streambuf;
void foo_say_hello_streambuf_wrapper1(Foo& foo, streambuf& output) {
streambuf::ostream os(output);
foo.say_hello_streambuf(os);
}
void foo_say_hello_streambuf_wrapper2(Foo& foo, bp::object& pyfile) {
streambuf output(pyfile);
foo_say_hello_streambuf_wrapper1(foo, output);
}
[...]
BOOST_PYTHON_MODULE('_test') {
[...]
bp::class_< Foo >("Foo", bp::init< >())
.def( bp::init< std::ostream & >(( bp::arg("os") ))
.def("say_hello_streambuf", &foo_say_hello_streambuf_wrapper2)
.def("say_hello_streambuf", &Foo::say_hello_streambuf)
.def("say_hello_streambuf", &foo_say_hello_streambuf_wrapper1)
[...]
}
I know how to create wrapper methods to delegate the member_functions,
but I don't know how to create a wrapper method for the constructor.
###### python test program ######
import _test as test
import sys
foo = test.Foo()
# Test ostream wrapping based on Ralf W. Grosse-Kunstleve's
# boost_adaptbx::python::streambuf class
foo.say_hello_streambuf(test.cout) # OK
foo.say_hello_streambuf(test.streambuf(sys.stdout)) # OK
foo.say_hello_streambuf(sys.stdout) # OK
# Test wrapping based on Michele De Stefano's
# mds_utils::python::oFileObj class
foo.say_hello_fileobj(test.cout) # OK
foo.say_hello_fileobj(test.oFileObj(sys.stdout)) # OK
foo.say_hello_fileobj(sys.stdout) # OK
# But I don't know how to create a wrapper to delegate this constructor
for ctor_arg in (
test.cout, # OK
test.streambuf(sys.stdout), # Boost.Python.ArgumentError
test.oFileObj(sys.stdout), # Boost.Python.ArgumentError
sys.stdout # Boost.Python.ArgumentError
):
try:
foo = test.Foo(ctor_arg)
except ArgumentError:
print "Argument error with argument %s" % ctor_arg
#####################
desired output of test program:
=====================
constructor1
hello streambuf
hello streambuf
hello streambuf
hello fileobj
hello fileobj
hello fileobj
constructor2
constructor2
constructor2
constructor2
actual output of test program:
=====================
constructor1
hello streambuf
hello streambuf
hello streambuf
hello fileobj
hello fileobj
hello fileobj
constructor2
Argument error with argument <_test.streambuf object at 0x00B75DB0>
Argument error with argument <_test.oFileObj object at 0x00B75E40>
Argument error with argument <open file '<stdout>', mode 'w' at 0x00373070>
More information about the Cplusplus-sig
mailing list