代码之家  ›  专栏  ›  技术社区  ›  gct

返回numpy数组别名内部数组时如何处理引用计数?

  •  1
  • gct  · 技术社区  · 7 年前

    我有一个名为ctcorrgen的类,它正在进行一些数值处理,并通过指向内部数组的常量指针一次返回一行结果。我想将这个内部数组包装成一个只读的numpy数组并返回它,如下所示:

    static inline PyObject* ctcorrgen_yield_row(object &object) {
        // extract corrgen base
        ctcorrgen &corrgen = extract<ctcorrgen&>(object);
    
        // get row of data
        const cfloat* row = corrgen.yield_row();
        if (row == nullptr) {
            return detail::none();        
        } else {
            // build read-only array around data
            npy_intp len = corrgen.framesize();
            return PyArray_New(
                &PyArray_Type, 1, &len, NPY_COMPLEX64, NULL, (void*)row, 0,
                NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_ALIGNED, NULL
            );
        }
    }
    

    我的问题是,如何设置这些内容,以便新的数组对象引用从中创建的对象,以便在我们处理完数组之前不会收集垃圾(从而破坏底层缓冲区)?我使用的是boost::python,但我怀疑这直接需要比我更多的关于python C-api的知识。

    1 回复  |  直到 7 年前
        1
  •  1
  •   gct    7 年前

    查看pyarrayObject的定义:

    typedef struct PyArrayObject {
        PyObject_HEAD
        char *data;
        int nd;
        npy_intp *dimensions;
        npy_intp *strides;
        PyObject *base;
        PyArray_Descr *descr;
        int flags;
        PyObject *weakreflist;
    } PyArrayObject;
    

    base pointer 以下内容:

    此成员用于保存指向 将用此数组的内容更新。

    警告

    // increment reference to ctcorrgen object and set base pointer
    // of array, this will establish an ownership link so that
    // ctcorrgen won't be destroyed before the array.
    incref(object.ptr());
    PyArray_SetBaseObject((PyArrayObject*)array, object.ptr());