1

I am trying to wrap a C++ class that handles binary values using Boost.Python. For this class, the "<<" operator has been defined as

std::ostream &operator<<(std::ostream &output, const bin &inbin);

I tried wrapping it with

class_<bin>("bin", init<>())
    .def(str(self));

However, the compilation throws this error:

boost/python/def_visitor.hpp:31:9: error: no matching function for call to
‘boost::python::api::object::visit(boost::python::class_<itpp::bin>&) const’

I am not sure how to resolve this error, anyone have an idea?

Reference: http://www.boost.org/doc/libs/1_31_0/libs/python/doc/tutorial/doc/class_operators_special_functions.html

fedepad
  • 4,509
  • 1
  • 13
  • 27
vidit
  • 957
  • 1
  • 8
  • 23
  • 1
    Why is this tagged SWIG and ctypes when it's about boost.python? – Flexo Jan 30 '17 at 18:27
  • @flexo The issue could be something basic related to wrapping operator<< for python – vidit Jan 30 '17 at 19:14
  • 2
    If you write a boost.python interface it has nothing to do with a swig one or a ctypes one. – Flexo Jan 30 '17 at 19:34
  • I agree with @Flexo, the swig and ctypes tags should go away... – fedepad Jan 30 '17 at 23:33
  • 1
    Which boost version are you using? And what about trying `.def(self_ns::str(self));` instead of `.def(str(self));`. Or `.def(self_ns::str(self_ns::self))` if the previous doesn't work? Does it help a bit? – fedepad Jan 30 '17 at 23:38
  • And might be related to this post: http://stackoverflow.com/questions/4362402/what-is-wrong-with-c-streams-when-using-boost-python – fedepad Jan 30 '17 at 23:39
  • Yes, that helps a lot @fedepad. The build works fine, but the output of "print obj" is still not perfect (prints the object type and address instead of stream output). Thanks. – vidit Jan 31 '17 at 09:17
  • Maybe at this point would be nice if you could share your implementation of `std::ostream &operator<<(std::ostream &output, const bin &inbin);` if you can. – fedepad Jan 31 '17 at 10:16
  • And did you try this `.def(self_ns::str(self_ns::self))` or `.def(self_ns::str(self));`? – fedepad Jan 31 '17 at 10:21
  • @fedepad Yes, that is what solved the build issue. I'm trying to wrap a third-party library and the "operator<<" implementation can be found at http://itpp.sourceforge.net/4.3.1/vec_8h_source.html. I wrapped with .def(self_ns::str(self)), but trying "print obj" results in "<[classname] object at [memory address]>" – vidit Jan 31 '17 at 11:04
  • yes, clear, but please try `.def(self_ns::str(self_ns::self));` also instead of `.def(self_ns::str(self));` before moving forward thinking about other stuff... – fedepad Jan 31 '17 at 11:17
  • 1
    I did, both .def(self_ns::str(self_ns::self)) and .def(self_ns::str(self)); give same result – vidit Jan 31 '17 at 11:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/134473/discussion-between-fedepad-and-vid). – fedepad Jan 31 '17 at 11:44

1 Answers1

6

This somehow seems to be covered in the following SO posts:
what is wrong with c++ streams when using boost.python?
Build problems when adding `__str__` method to Boost Python C++ class

So, according to the previous posts, you should try to substitute

.def(str(self));  

with either

.def(self_ns::str(self)); 

or

.def(self_ns::str(self_ns::self))  

It seems to have resolved the same problem in those cases.

If the above doesn't work, try writing a custom wrapper. For example, you may define a print_wrap function as:

#include <sstream>
std::string print_wrap(const classname &c)
{
  std::ostringstream oss;
  oss << "HelloWorld " << c.var1 << " " << c.var2;
  return oss.str();
}

And then in the class_<classname>("py_classname") definition use,

.def("__str__", &print_wrap)

Then in Python you should be able to get

>>> obj = py_classname(1,2)  #var1=1, var2=2
>>> print obj
>>> HelloWorld 1 2
Community
  • 1
  • 1
fedepad
  • 4,509
  • 1
  • 13
  • 27