Cython:使用 C++ 流
Cython: working with C++ streams
问题
如何使用来自 Cython 的 C++ 流(如 std::ifstream
或 ostream
)?在 C++ 中,您可以执行以下操作:
std::ofstream output { filename, std::ios::binary };
output.write(...);
您将如何在 Cython 中实现相同的目标?
当前状态
我已经在 Cython 中包装了来自 fstream 的结构,以便我可以在函数声明中使用它们的名称,但棘手的部分是使用(也许在 Cython 中包装)write 方法并创建流。我还没有在互联网上找到任何代码示例。
P.S。
我知道一个可能的答案是只使用 Python 的 IO,但我需要 pass/return 与我交互的 C++ 代码之间的流。
这是包装流声明的代码:
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
与包装任何其他 C++ class 相比,C++ iostream 并没有什么特别之处。唯一棘手的一点是访问 std::ios_base::binary
,我告诉 Cython std::ios_base
是一个命名空间而不是 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
要补充的另一件事是,我没有为完整的模板化 class 层次结构烦恼——如果您还想要 wchar
变体,这可能会有用,但仅告诉 Cython 你实际使用的 classes。
问题
如何使用来自 Cython 的 C++ 流(如 std::ifstream
或 ostream
)?在 C++ 中,您可以执行以下操作:
std::ofstream output { filename, std::ios::binary };
output.write(...);
您将如何在 Cython 中实现相同的目标?
当前状态
我已经在 Cython 中包装了来自 fstream 的结构,以便我可以在函数声明中使用它们的名称,但棘手的部分是使用(也许在 Cython 中包装)write 方法并创建流。我还没有在互联网上找到任何代码示例。
P.S。 我知道一个可能的答案是只使用 Python 的 IO,但我需要 pass/return 与我交互的 C++ 代码之间的流。
这是包装流声明的代码:
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
与包装任何其他 C++ class 相比,C++ iostream 并没有什么特别之处。唯一棘手的一点是访问 std::ios_base::binary
,我告诉 Cython std::ios_base
是一个命名空间而不是 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
要补充的另一件事是,我没有为完整的模板化 class 层次结构烦恼——如果您还想要 wchar
变体,这可能会有用,但仅告诉 Cython 你实际使用的 classes。