How can I pass null to an external library, using ctypes, with an argument declared with ctypeslib.ndpointer?
If (like me) you are dealing with multiple different array types, a slightly nicer workaround is to wrap ndpointer
itself:
import numpy as npfrom numpy.ctypeslib import ndpointerdef wrapped_ndptr(*args, **kwargs): base = ndpointer(*args, **kwargs) def from_param(cls, obj): if obj is None: return obj return base.from_param(obj) return type(base.__name__, (base,), {'from_param': classmethod(from_param)})ComplexArrayType = wrapped_ndptr(dtype=np.complex128, ndim=1, flags='C_CONTIGUOUS')DoubleArrayType = wrapped_ndptr(dtype=np.float64, ndim=1, flags='C_CONTIGUOUS')
Following the excellent advice from eryksun in a comment I subclassed the type returned by ctypeslib.ndpointer
and implemented an overridden from_param
. This is a little tricky as it has to be done using class factory techniques, because the class returned by ctypeslib.ndpointer
is made by a factory.
The code that I ended up with:
_ComplexArrayTypeBase = numpy.ctypeslib.ndpointer(dtype=numpy.complex128, ndim=1, flags='C_CONTIGUOUS')def _from_param(cls, obj): if obj is None: return obj return _ComplexArrayTypeBase.from_param(obj)ComplexArrayType = type( 'ComplexArrayType', (_ComplexArrayTypeBase,), {'from_param': classmethod(_from_param)})
Many thanks to eryksun for his (as always) expert advice.