The Problem
How does one use c++ streams (like std::ifstream
or ostream
) from Cython? In c++, you could do the following:
std::ofstream output { filename, std::ios::binary };
output.write(...);
How would you achieve the same in Cython?
Current status
I have wrapped the structures from fstream in Cython so that I can use their names in function declarations, but the tricky part is to use (wrap in Cython, perhaps) the write method and to create the streams. I haven't found any code examples on the internet.
P.S. I know one possible answer would be to just use Python's IO but I need to pass/return the streams to and from C++ code that I'm interfacing with.
This is the code that wraps the stream declarations:
cdef extern from "<iostream>" namespace "std":
cdef cppclass basic_istream[T]:
pass
cdef cppclass basic_ostream[T]:
pass
ctypedef basic_istream[char] istream
ctypedef basic_ostream[char] ostream
There isn't much particularly special about the c++ iostreams compared to wrapping any other C++ class. The only tricky bit was getting access to std::ios_base::binary
, which I did by telling Cython that std::ios_base
was a namespace and not a class.
# distutils: language = c++
cdef extern from "<iostream>" namespace "std":
cdef cppclass ostream:
ostream& write(const char*, int) except +
# obviously std::ios_base isn't a namespace, but this lets
# Cython generate the correct C++ code
cdef extern from "<iostream>" namespace "std::ios_base":
cdef cppclass open_mode:
pass
cdef open_mode binary
# you can define other constants as needed
cdef extern from "<fstream>" namespace "std":
cdef cppclass ofstream(ostream):
# constructors
ofstream(const char*) except +
ofstream(const char*, open_mode) except+
def test_ofstream(str s):
cdef ofstream* outputter
# use try ... finally to ensure destructor is called
outputter = new ofstream("output.txt",binary)
try:
outputter.write(s,len(s))
finally:
del outputter
The other thing to add is that I haven't bothered with the full templated class heirarchy - that might be useful if you also want the wchar
variants, but it's much easier to only tell Cython about the classes you're actually using.
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