I've accomplished something similar by putting the logic in C++ layer, although you'll have to then deal with getting the right Python include directory when you compile. Here's a small snippet which is part of a larger class and wrapping framework. The portions you care about will be between the #if statements. Your case might be easier if you don't have templated array types.
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 0)
template <typename T>
void array_destructor(PyObject* obj) {
void* ptr = PyCapsule_GetPointer(obj, traits<T>::name);
if (ptr != NULL)
delete (array<T>*) ptr;
}
#else
template <typename T>
void array_destructor(void* ptr) {
if (ptr != NULL)
delete (array<T>*) ptr;
}
#endif
template <typename T>
PyObject* steal(array<T>& x, PyObject* subtype) {
if (!x.owndata())
throw runtime_error("array does not own data; cannot steal ownership");
PyObject *arr = view(x, subtype);
array<T>* ptr = new array<T>();
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 0)
PyObject* cap = PyCapsule_New((void*) ptr, traits<T>::name,
&array_destructor<T>);
#else
PyObject* cap = PyCObject_FromVoidPtr((void*) ptr, &array_destructor<T>);
#endif
PyArray_BASE(arr) = cap;
// Transfer array ownership into the capsule.
ptr->swap(x);
return arr;
}