如何在 Cython 中构建 iostream 对象(例如 cout)并将其传递给 c++ 函数?
Posted
技术标签:
【中文标题】如何在 Cython 中构建 iostream 对象(例如 cout)并将其传递给 c++ 函数?【英文标题】:How to build in Cython an iostream object (e. g. cout) and pass it to a c++ function? 【发布时间】:2017-12-10 01:59:54 【问题描述】:我正在尝试包装以下 C++ 类: 打印.h
#include <string>
using namespace std;
class ControlParameters
public:
ControlParameters();
~ControlParameters();
void Initialize(string input, ostream& log);
;
打印.cpp
#include "print.h"
#include <iostream>
ControlParameters::ControlParameters()
ControlParameters::~ControlParameters()
void ControlParameters::Initialize(string input, ostream& log)
log<<"Output = "<< input <<endl;
我的 String.pyx 如下所示:
from libcpp.string cimport string
cdef extern from "<iostream>" namespace "std":
cdef cppclass ostream:
┆ ostream& write(const char*, int) except +
cdef extern from "print.h":
cdef cppclass ControlParameters:
┆ ControlParameters() except +
┆ void Initialize(string, ostream&)
cdef class PyControlParameters:
cdef ControlParameters *thisptr
def __cinit__(self):
┆ self.thisptr = new ControlParameters()
def __dealloc__(self):
┆ del self.thisptr
def PyInitialize(self, a,b):
self.thisptr.Initialize(a, b)
编译 String.pyx 后,出现以下错误:
Compiling String.pyx because it changed.
[1/1] Cythonizing String.pyx
Error compiling Cython file:
------------------------------------------------------------
...
def __cinit__(self):
self.thisptr = new ControlParameters()
def __dealloc__(self):
del self.thisptr
def PyInitialize(self, a,b):
self.thisptr.Initialize(a, b)
^
------------------------------------------------------------
String.pyx:18:39: Cannot convert Python object to 'ostream'
Traceback (most recent call last):
File "setup.py", line 7, in <module>
language="c++"
File "/usr/local/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 1039, in cythonize
cythonize_one(*args)
File "/usr/local/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 1161, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: String.pyx
我读到here 我必须构建自己的 ostream 类才能获得 ostream 对象。但是我如何定义这个对象呢? 我想我需要一个将我的 python 对象转换为 ostream 对象的函数。我怎么能实现这样的功能?
【问题讨论】:
您实际上想对输出做什么?发送到文件?发送到标准输出?两者之间有选择吗? @DavidW 我想把它发送到标准输出。在 c++ 中,我会通过一个 cout。 【参考方案1】:如果您总是想将其发送到 cout,那么最简单的方法是在 Cython 中执行此操作,而不是在 Python 中处理第二个参数。将 cout 添加到您的cdef extern
:
cdef extern from "<iostream>" namespace "std":
# define ostream as before
ostream cout
然后在做 PyInitialize 为:
def PyInitialize (self, a):
self.thisptr.Initialize(a,cout)
这样就省去了为 Cython 编写完整的 ostream 包装类的工作。
【讨论】:
以上是关于如何在 Cython 中构建 iostream 对象(例如 cout)并将其传递给 c++ 函数?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Windows 8.1 中的 anaconda(python3.6) 中将 cython pyx 构建为 pyd?
如何构建和分发依赖于第三方 libFoo.so 的 Python/Cython 包