Skip to content Skip to sidebar Skip to footer

PyArray_SimpleNewFromData

So I am trying to write a C function that accepts a numpy array object, extracts the data, does some manipulations and returns another c array as a numpy array object. Everything w

Solution 1:

The technique described in the link you didn't understand is a good one: create a Python object that knows how to free your memory when destroyed, and make it the base of the returned array.

It sounds like you might have been overwhelmed by the complexity of creating a new extension type. Fortunately, that's not necessary. Python comes with a type designed to perform arbitrary C-level cleanup when destroyed: capsules, which bundle together a pointer and a destructor function and call the destructor when the capsule is destroyed.

To create a capsule for your memory, first, we define a destructor function:

void capsule_cleanup(PyObject *capsule) {
    void *memory = PyCapsule_GetPointer(capsule, NULL);
    // I'm going to assume your memory needs to be freed with free().
    // If it needs different cleanup, perform whatever that cleanup is
    // instead of calling free().
    free(memory);
}

And you set a capsule as your array's base with

PyObject *capsule = PyCapsule_New(data, NULL, capsule_cleanup);
PyArray_SetBaseObject((PyArrayObject *) arr, capsule);
// Do not Py_DECREF the capsule; PyArray_SetBaseObject stole your
// reference.

And that should ensure your memory gets freed once it's no longer in use.


Solution 2:

While the PyCapsule approach works more generally, you can get numpy to free the memory in the array for you when it's garbage collected by setting the OWNDATA flag.

double *data = some_function_that_returns_a_double_star(x, y, z);
PyObject *arr = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, (void *)data);
PyArray_ENABLEFLAGS((PyArrayObject*) arr, NPY_ARRAY_OWNDATA);

Post a Comment for "PyArray_SimpleNewFromData"