numpy array C api

后端 未结 2 1789
清酒与你
清酒与你 2020-12-31 19:23

I have a C++ function returning a std::vector and I want to use it in python, so I\'m using the C numpy api:

static PyObject *
py_integrate(PyObject *self, P         


        
2条回答
  •  半阙折子戏
    2020-12-31 20:00

    Your std::vector object appears to be local to that function. PyArray_SimpleNewFromData does not make a copy of the data you pass it. It just keeps a pointer. So once your py_integrate function returns, the vector is deallocated. The print works the first time because nothing has written over the freed memory yet, but by the time you get to the next print, something else has used that memory, causing the values to be different.

    You need to make a NumPy array that owns its own storage space and then copy the data into it.

    Alternatively, allocate your vector on the heap. Then store a pointer to it in a CObject. Provide a destructor that deletes the vector. Then, take a look at the C-level PyArrayObject type. It has a PyObject * member called base. Store your CObject there. Then when the NumPy array is garbage collected, the reference count on this base object will be decremented, and assuming you haven't taken a copy of it elsewhere, your vector will be deleted thanks to the destructor you provided.

    Fixer-upper

    You forgot to actually create the PyArray. Try this:

    (You didn't post DeleteVector, so I can only hope that it's right)

    std::vector *vector = new std::vector();
    vector->push_back(1.);
    PyObject *py_integral = PyCObject_FromVoidPtr(vector, DeleteVector);
    npy_intp size = {vector->size()};
    PyObject *out = PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, &((*vector)[0]));
    ((PyArrayObject*) out)->base = py_integral;
    return out;
    

    Note: I'm not a C++ programmer, so I can only assume that &((*vector)[0]) works as intended with a pointer to a vector. I do know that the vector reallocate its storage area if you grow it, so don't increase its size after getting that pointer or it won't be valid anymore.

提交回复
热议问题