Cython 中动态大小的对象数组
Posted
技术标签:
【中文标题】Cython 中动态大小的对象数组【英文标题】:Dynamically sized array of objects in Cython 【发布时间】:2018-06-24 01:19:21 【问题描述】:如何在 Cython 中执行与以下 C++ 代码等效的操作?
typedef vector<double> dvec;
dvec *arr = new dvec[n]; // n is an unsigned int (unknown at compile time)
// do something with arr; for example...
arr[0].push_back(10);
cout << arr[0][0] << endl;
我尝试为 n 个向量分配内存,但后来我不知道如何在 Cython 中进行新的放置。任何帮助将不胜感激。
【问题讨论】:
我不明白你在这里问什么。 Placement new 类似于double *d = new(arr[0]) double
,您可以在其中在已分配的内存位置构造一个新的double。你没有在你的代码中这样做,我无法想象它在这段代码中或附近会有什么用处。
我正在尝试将此代码翻译成 Cython。我不知道怎么。我建议将 malloc 和 Placement new 结合起来作为一种可能性(但我认为 Cython 中没有新的位置)。
向量的向量怎么样?除非这是你可以用 Python 类来做的事情。
@DavidW:+1。是的,我最终放弃并用vector[vector[double]]实现它,但我只是好奇是否可以这样做。
【参考方案1】:
您似乎无法在 Cython 中执行 array new (new something[n]
)。最简单的解决方案是创建 1 行 C++ 函数来执行数组新建和数组删除,然后调用它们。
template <typename T>
T* array_new(int n)
return new T[n];
template <typename T>
void array_delete(T* x)
delete [] x;
从以下 Cython 文件调用
# distutils: language = c++
from libcpp.vector cimport vector
ctypedef vector[double] dvec
cdef extern from "cpp_funcs.hpp":
T* array_new[T](int)
void array_delete[T](T* x)
def example(int n):
cdef dvec* arr = array_new[dvec](n)
try:
if n>0:
arr[0].push_back(10)
print(arr[0][0])
finally:
array_delete(arr)
鉴于 Cython 对 C++ 的支持有限,而且有些地方很尴尬(而且你必须对 C++ 有很好的理解才能使用它)我认为编写少量 C++ 代码通常是一个合理的解决方案,并且可以节省不少时间。不过,有些人似乎想不惜一切代价避免这种情况......
我仍然建议使用向量向量 (vector<vector<double>>
),因为您可以免费获得内存管理。更好的是坚持使用 Python 类型并使用 numpy 数组列表,但如果您想与外部 C++ 代码交互,这可能不合适。
【讨论】:
【参考方案2】:作为@DavidW 答案的补充:由于 Cython 0.28 有一个新功能允许verbatim C-code。它的优点是可以无缝使用这种小型 C/C++ 包装器:
cdef extern from *:
"""
template <typename T>
T* array_new(int n)
return new T[n];
template <typename T>
void array_delete(T* x)
delete [] x;
"""
T* array_new[T](int)
void array_delete[T](T* x)
from libcpp.vector cimport vector
.... and so on
无需创建外部头文件。
【讨论】:
以上是关于Cython 中动态大小的对象数组的主要内容,如果未能解决你的问题,请参考以下文章