The Cython docs discuss passing a pointer to a memoryview by using, e.g.:
cdef double[::1] x_view = x # some array
cdef double* ptr = &x_view[0]
however, when that array x has no elements (x.size == 0), trying to access x_view[0] fails. For the C library to which I am making an interface, passing a NULL pointer leads to a segfault, so I can't just check x.size and pass NULL.
Instead, I need to pass a pointer to a valid memory block of size 0. Using the old numpy array interface and passing <double*>x.data works even in the case of an empty array like x = np.array([]), but I am trying to move to using typed memoryviews with fused types to avoid code duplication and have more easily-enforceable type safety.
Is there an accepted way to handle this situation? Or are there plans for a feature like x_view.ptr that would handle this case internally?
I had to look this up in the Cython source to find it, but memoryviews do have an undocumented attribute _data and thus you can do
cdef double* ptr = <double*>x_view._data
(the cast is because the data attribute is just typed generically as char*).
With that said, I'm not completely sure I'd trust it for your purposes for a couple of reasons:
NULL pointer to your function fails, then that suggests your function is dereferencing the pointer itself (which is dubious for length-0 arrays).To me that suggests you should do something like:
cdef double dummy_double
cdef double* ptr = &x_view[0] if x_view.shape[0] else &dummy_double
and then you know you're passing a pointer to some valid memory.