包装一个函数,在 Cython 中返回复杂类型的向量
Wrapping a function returning a Vector of Complex types in Cython
我目前正在尝试包装我创建的C++类。其中一个函数返回包含复杂浮点数的向量向量:
std::vector<std::vector<std::complex<float>>>
我的 DataBridge.pxd 文件如下所示:
# distutils: language = c++
from libcpp cimport bool
from libcpp cimport float
from libcpp.vector cimport vector
from libcpp.complex cimport complex
from libc.float cimport float
cimport numpy as np
import numpy as np
cdef extern from "projectxcpp/bridge.cpp":
pass
# Declare the class with cdef
cdef extern from "projectxcpp/bridge.hpp":
cdef cppclass DataBridge:
DataBridge() except +
void start()
void stop()
bool isDataReady()
vector[vector[complex[float]]] getData()
我的bridge.hpp文件如下所示:
#ifndef BRIDGE_HPP
#define BRIDGE_HPP
#include <vector>
#include <complex>
...
class DataBridge {
public:
int start(void);
int stop(void);
bool isDataReady(void);
std::vector<std::vector<std::complex<float>>> getData(void);
private:
...
};
#endif
然后,尝试运行 setup.py,给出以下消息:
[1/1] Cythonizing snowconecpp.pyx
Error compiling Cython file:
------------------------------------------------------------
...
DataBridge() except +
void start()
void stop()
bool isDataReady()
vector[vector[complex[float]]] getData()
^
------------------------------------------------------------
DataBridge.pxd:24:29: Array size must be a compile time constant
Error compiling Cython file:
------------------------------------------------------------
...
DataBridge() except +
void start()
void stop()
bool isDataReady()
vector[vector[complex[float]]] getData()
^
------------------------------------------------------------
DataBridge.pxd:24:29: unknown type in template argument
Traceback (most recent call last):
File "setup.py", line 15, in <module>
setup(ext_modules=cythonize("projectxcpp.pyx", language_level="3"))
File ".../lib/python3.6/site-packages/Cython/Build/Dependencies.py", line 1096, in cythonize
cythonize_one(*args)
File ".../lib/python3.6/site-packages/Cython/Build/Dependencies.py", line 1219, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: projectxcpp.pyx
我的 setup.py 文件仅包含:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("projectxcpp.pyx", language_level="3"))
当我的包装器中将类型声明为complex[float] e
或vector[vector[float]] e
时,这些类型将解析并移至下一步编译。
只是想知道在 Cython 的向量中放置复杂类型是否有特殊要求 - 似乎无法为涉及C++包装的这种情况或类似情况找到答案。
我的最终目标是能够将这些数据读出到 numpy 数组中。如果有更好的方法,也请让我意识到这一点 - 谢谢!
我认为问题是complex
已经是 Python/Cython 中的一种类型(并且由于与 C 重叠或C++复杂,在某些地方处理得也有些糟糕......如果您重命名它,或者按其完整路径寻址,它可以工作
from libcpp.complex cimport complex as cpp_complex
# later
vector[vector[cpp_complex[float]]]
或
cimport libcpp.complex
# later
vector[vector[libcpp.complex.complex[float]]]
对于问题的更一般部分:我倾向于不为这样的 Numpy 数组提供数据。部分原因是我真的不喜欢将 2D 数组定义为指针到指针或矢量的矢量。您最好使用与形状信息一起存储的 1D 数组/矢量,以便对其进行索引。
与 Numpy 接口有几个选项:
如果您事先知道大小,则使用 Numpy 分配内存并将该内存传递到C++(您可以获得指向 Numpy 数组的第一个元素的指针(。这样,C++代码会修改 Numpy 的内存,您不必复制数据。
如果要使用 C++ 分配内存,则可以使用实现缓冲区协议的 Cython 类包装它。内存由C++管理,但 Numpy 无需复制即可直接访问内存。(您可能需要实现移动构造函数以避免复制,但这相当简单(。
您可以使用 NumpyC API 函数
PyArray_SimpleNewFromData
让 Numpy 包装内存。这需要小心以确保在正确的时间释放它。您可以执行当前正在执行的操作并复制数据。这实现起来非常简单,但每次要将数据从C++移动到 Python 时都会添加一个复制操作。
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何在 Cython 中定义返回 cpp 定义类型的函数?
- 如何将 Python 对象转换为 Cython 扩展类型的 std::vector 并返回?
- 包装一个函数,在 Cython 中返回复杂类型的向量
- 如何为返回枚举元组的 C++ 函数编写 cython 包装器?
- 在Cython中定义C 结构返回类型
- Cython:如何包装返回C++对象的C++函数
- 包装一个使用char**[in/out]的C函数调用,以在cython中返回一个python列表
- 无法在 Cython 中带有命名空间的C++代码中返回 C 结构
- 如何使用 Cython 连接返回C++自定义类的函数
- 如何使用Cython将返回C++对象的函数公开给Python
- 如何在Cython中从另一个包装对象返回包装的c++对象
- 返回Cython数组
- 如何在Cython中返回新的c++对象
- 包装方法返回 c++ std::array<std::string, 4> in cython
- Cython-将C++函数返回的C++(矢量和非矢量)对象公开给Python