如何在Cython构建一个iostream对象(例如Cout)并将其传递到C 函数

How to build in Cython an iostream object (e. g. cout) and pass it to a c++ function?

本文关键字:函数 Cout 例如 iostream Cython 构建 一个 对象      更新时间:2023-10-16

我正在尝试包装以下C 类:
print.h

#include <string>
using namespace std;
class ControlParameters
{
public:
    ControlParameters();
    ~ControlParameters();
    void Initialize(string input, ostream& log);
};

print.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

我在这里读到,我必须构建自己的Ostream类才能获取一个Ostream对象。但是如何定义这个对象?我认为我需要一个将我的Python对象转换为Ostream对象的函数。我如何实现此类函数?

如果您始终想将其发送到COUT,那么最简单的方法是在Cython中进行此操作,而不是处理Python中的第二个参数。将COUT添加到您的cdef extern

cdef extern from "<iostream>" namespace "std":
  # define ostream as before
  ostream cout

然后在do pyinitialize中为:

def PyInitialize (self, a):
  self.thisptr.Initialize(a,cout)

节省了为Cython编写完整的Ostream包装班的努力。