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&lt;vector&lt;double&gt;&gt;),因为您可以免费获得内存管理。更好的是坚持使用 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 中动态大小的对象数组的主要内容,如果未能解决你的问题,请参考以下文章

如何调整动态分配的多态对象数组的大小?

获取动态分配的数组大小

在VBScript中调整对象内部的数组大小

在 C++ 中读取具有动态数组的对象

数据结构中的数据——动态数组的创建

在 C++ 中动态调整数组的大小