Update 2: I'm not sure why this is still being upvoted (March 2014). This appears to be fixed since I asked this question many years ago. Make sure you're using a recent version of boost.
UPDATE: Perhaps C++ streams need to be initialized in order to format numbers, and the initialization is not happening when the shared library is loaded in Python?
I am calling
cout << 1 << "!" << endl;
in a method that is exported to a shared library via boost.python. It doesn't print anything, but if I do
cout << "%" << "!" << endl;
it works.
This is important because I want to do this:
ostream& operator <<(ostream &os, const Bernoulli& b) {
ostringstream oss;
oss << b.p() * 100.0 << "%";
return os << oss.str();
}
I exposed that by doing this:
BOOST_PYTHON_MODULE(libdistributions)
{
class_<Bernoulli>("Bernoulli")
.def(init<>())
.def(init<double>())
.def("p", &Bernoulli::p)
.def("set_p", &Bernoulli::set_p)
.def("not_p", &Bernoulli::not_p)
.def("Entropy", &Bernoulli::Entropy)
.def("KL", &Bernoulli::KL)
.def(self_ns::str(self))
;
}
but when I call the str
method in python on a Bernoulli object, I get nothing. I suspect the simpler cout problem is related.
I also run into this problem a while ago, using self_ns as outlined in the answers here Build problems when adding `__str__` method to Boost Python C++ class
The reason for using self_ns is explained by Dave himself here http://mail.python.org/pipermail/cplusplus-sig/2004-February/006496.html
Just for the sake of debugging, please try
inline std::string toString(const Bernoulli& b)
{
std::ostringstream s;
s << b;
return s.str();
}
And replace .def(self_ns::str(self))
with
class_<Bernoulli>("Bernoulli")
[...]
.def("__str__", &toString)
Have you tried using boost::format
instead? Since you are already using boost
, it shouldn't be too much of a hassle.
boost::format( "%d%%" ) % ( b.p() * 100.0 )
Another thing, try passing std::endl
explicitly to the output os
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With