0

I am using cppyy for a native c++ project. I have a function that takes in a std::ostream& object and I am not sure how to create something that calls it from python.

I have tried doing

import io

output = io.StringIO()

CPP_FUNCTION(output)

print(output.getvalue())

But I am getting

TypeError: void CPP_FUNCTION(std::ostream& outputstream) =>
    TypeError: could not convert argument 1
shouriha
  • 79
  • 6
  • https://cppyy.readthedocs.io/en/latest/search.html?q=stream&check_keywords=yes&area=default -- seems you're out of luck. Depending on what you need, you can probably use filedescriptors (`int` type, like `stdin`, `stdout`, `stderr`) and/or use multiprocessing and redirect the input/output. Maybe you can also write some gluecode in C++ that adapts between a Python `StringIO` and a C++ `streambuf` to get this going. – Ulrich Eckhardt Jan 10 '23 at 21:54
  • Oh no! @WimLavrijsen please save me – shouriha Jan 10 '23 at 21:58
  • Hi, @shourinha. Please, share with us the definition of `StringIO()` it's important to know what this method returns. – Jorge Omar Medra Jan 10 '23 at 22:00
  • That's a Python builtin, @JorgeOmarMedra!? – Ulrich Eckhardt Jan 10 '23 at 22:00
  • @JorgeOmarMedra CPP_FUNCTION returns void if that is what you are asking. StringIO() is type `_io.StringIO` – shouriha Jan 10 '23 at 22:02
  • 1
    it might help you: https://bitbucket.org/wlav/cppyy/issues/256/issue-capturing-stdout-stderr – Jorge Omar Medra Jan 10 '23 at 22:04
  • I'm not sure what kind of object is returning StringIO, but by the name, I'll try with `std::stringstream&` instead of `std::ostream&` – Jorge Omar Medra Jan 10 '23 at 22:06

1 Answers1

1

It is what Jorge said in the comments: for a C++ function taking an ostream to work, you are going to have to provide an object that implements C++'s ostream. Python's io.StringIO() has no relation to std::ostream. In fact, the two don't even use the same underlying data type for their buffers, so it's not possible to build one interface on top of the other.

What you can do, is capture things the C++ way, then extract the string and convert. This comes at the cost of an extra copy (unless of course the needed result is really an std::string to be passed on to another C++ function, in which case no conversion is needed).

Example code:

import cppyy

cppyy.cppdef(r"""\
void example(std::ostream& outputstream) {
    outputstream << "Hello, World!";
}""")

output = cppyy.gbl.std.ostringstream()

cppyy.gbl.example(output)

# str() creates a std::string; converted to Python str by print()
print(output.str())
Wim Lavrijsen
  • 3,453
  • 1
  • 9
  • 21