在 cython 中将 C++ 对象转换为 python 对象?
Posted
技术标签:
【中文标题】在 cython 中将 C++ 对象转换为 python 对象?【英文标题】:Converting C++ object to python object in cython? 【发布时间】:2017-06-10 00:40:45 【问题描述】:我的第一个 cython 程序遇到了困难,所以如果我有一个愚蠢的问题,请不要气馁。
这是我的例子:
c_foo.h:
// c_foo.h
class foo:
public:
....
std::unique_ptr<2DVector> get_cFoo_unique_ptr(); // Vec2D<T> is a vector of vectors of T
// std::vector<std::vector<T>>
private:
std::unique_ptr<Vec2D> cFoo_unique_ptr; // Vec2D<T> is a vector of vectors of T
foo.pyx: # foo.pyx 进口赛通 ... # 其他导入 从 cython.operator cimport unique_ptr as cpp_unique_ptr
cdef extern from c_foo.h:
cdef cppclass c_foo:
...
cpp_unique_ptr get_cFoo_unique_ptr()
cdef class py_foo:
cdef c_foo* cFoo
...
def get_Vec2D(self):
return self.cFoo.get_cFoo_unique_ptr().get()
所以,我在这里要做的是从 C++ unique_ptr 获取数据并在 python 中返回它们。 cython 抱怨它。
def get_Vec2D(self):
return self.cFoo.get_cFoo_unique_ptr().get()
----------------------------------------------------------
foo.pyx:xx:xx: Cannot convert 'T *' to Python object
另一个尝试是我尝试其他方式来声明向量的 cython unique_ptr:
# foo.pyx
import cython
... # other import
from cython.memory cimport unique_ptr as cpp_unique_ptr
from cython.vector cimport vector as cpp_vector
cdef extern from c_foo.h:
cdef cppclass c_foo:
...
cpp_unique_ptr[cpp_vector[cpp_vector[T]]] get_cFoo_unique_ptr()
cdef class py_foo:
cdef c_foo* cFoo
...
def get_Vec2D(self):
return self.cFoo.get_cFoo_unique_ptr().get()
还是同样的错误:
Cannot convert 'vector[vector[T]] *' to Python object
所以,我的问题是如何在 cython 中访问 C++ unique_ptr 的数据? 对于通过 cython 在 C++ 和 python 之间传递数据,我应该知道什么好的做法吗?
谢谢
【问题讨论】:
第二个选项靠近右边。如果 Cython 不知道T
是什么,它应该如何将其转换为 Python 对象?
见question for a similar answer。 TL;DR - 您需要一个工厂类来将 C++ 类转换为 Python 对象以便返回。 Cython 会自动为内置类型执行此操作,但不能用于自定义结构或类。
【参考方案1】:
这种事情让我困惑了很久。我只在 C 环境中使用过 Cython,而不是 C++,所以我不知道您的案例中可能存在的其他选项。但我会解释我是如何做到的,希望对您有所帮助。
您必须在 Cython 函数的末尾创建 Python 对象,因为这些是唯一有效的返回值。这意味着,除其他外,您不能返回指针或 C 数组。例如,假设我有一个计算双精度数组的 Cython 函数 f:
def f():
cdef double aa[1000]
cdef int i
# ....
# some calculation that populates aa
# ....
# Now I can't just return aa because aa isn't a Python object.
# I have to convert it to a Python list:
a = []
for i in range(1000):
a.append(aa[i]) # Cython knows how convert one C float to one Python float
return a
【讨论】:
以上是关于在 cython 中将 C++ 对象转换为 python 对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Cython 中将大型 malloc 数组返回或保存为 Python 对象?