python - 如何在 Cython 中构建 iostream 对象(例如 cout)并将其传递给 C++ 函数?

标签 python c++ cython iostream

我正在尝试包装以下 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 对象的函数。我该如何实现这样的功能?

最佳答案

如果您总是想将它发送到 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 包装器类的工作。

关于python - 如何在 Cython 中构建 iostream 对象(例如 cout)并将其传递给 C++ 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47735139/

相关文章:

python - 有没有用 python 编写的基于 Web 的电子邮件客户端?

python - 使用生成器表达式导致 Python 挂起

python - 子类化容​​器时添加基类类型提示

python - numpy数组任意列之间的(内存)高效操作

python - 制作一个 bool 数组

python - 与使用常规配置文件相比,Hydra 有哪些优势

c++ - 处理条件编译的多个条件的最佳方法

c++ - 为什么 C++ 不支持堆栈上的动态数组?

c++ - 使用 cmake 构建我的 C++ 项目的正确方法?

python - 如何使用 Cython 围绕 C 结构编写完整的 Python 包装器?