Numpy C++: как перебрать PyArrayObject без segfault

Для меня все следующее приводит к segfault:

my_array->descr->subarray->shape;
my_array->dimensions;
PyArray_SHAPE(my_array);
PyArray_DIMS(my_array);
PyArray_ITEMSIZE(my_array);
PyArray_NBYTES(my_array);

Моя функция выглядит так:

static PyObject* exterior(PyObject* self, PyArrayObject* old_simplices_array)
{//code here

Остальная часть моего файла cpp выглядит так:

#include "Python.h"
#include "numpy/arrayobject.h"

/* function */

static PyMethodDef compiled_methods[] = 
{
    {"_exterior",(PyCFunction)exterior , METH_VARARGS},
    {NULL,      NULL}        /* Sentinel */
};

PyMODINIT_FUNC init_alto(void)
{
    (void) Py_InitModule("_alto", compiled_methods);
    import_array();
}

Код Python, который передает массив «внешнему», просто передает массив NxM uint. Эта часть работает. Я могу получить доступ к шагам и данным массива. Я просто не могу определить границы итерации. Я работаю внутри шалфея, если это имеет значение.

Как я должен перебирать массив без segfaulting? Если ответ очевиден, пожалуйста, защитите свой ответ от идиотизма.

Чтобы лучше понять, как выглядит функция, см. здесь.


person Alex Eftimiades    schedule 13.09.2013    source источник


Ответы (1)


В прошлом я делал следующее для перебора PyArrayObject:

static PyObject *func1(PyObject *self, PyObject *args) {
    PyArrayObject *X;
    int ndX;
    npy_intp *shapeX;
    PyArray_Descr *dtype;
    NpyIter *iter;
    NpyIter_IterNextFunc *iternext;

    PyArg_ParseTuple(args, "O!", &PyArray_Type, &X);
    ndX = PyArray_NDIM(X);
    shapeX = PyArray_SHAPE(X);
    dtype = PyArray_DescrFromType(NPY_DOUBLE);

    iter = NpyIter_New(X, NPY_ITER_READONLY, NPY_KEEPORDER, NPY_NO_CASTING, dtype);
    if (iter==NULL) {
        return NULL;
    }
    iternext = NpyIter_GetIterNext(iter, NULL);
    dataptr = (double **) NpyIter_GetDataPtrArray(iter);

    do {
        cout << **dataptr << endl;
    } while (iternext(iter));

    NpyIter_Deallocate(iter);
    return Py_BuildValue(something);
}

Чтобы узнать больше, перейдите по этой ссылке: http://docs.scipy.org/doc/numpy/reference/c-api.iterator.html

person Joel Vroom    schedule 13.09.2013
comment
Я думал, что ваш пример работает, но я только что получил NULL iter. Вы уверены, что вам не нужно делать ничего особенного с массивом, который python передает в C? - person Alex Eftimiades; 13.09.2013
comment
Я отредактировал приведенное выше, чтобы показать, как анализируется X. Это работает для меня. PyArg_ParseTuple(args, O!, &PyArray_Type, &X); - person Joel Vroom; 13.09.2013