受到另一个answer的启发,我有一个ctypes函数,我使用ctypeslib.ndpointer
调用:
lib.foo.argtypes = [ctypeslib.ndpointer(np.complex64, ndim=1, flags='C'), POINTER(c_int)]
外部函数声明如下:
void foo(cmplx_float *array, int *length)
我的问题是我想要两次调用该函数。我第一次想将nullptr
传递给array
参数,以便找出所需的长度。然后第二次,我将传递一个numpy数组。
所以我这样做:
lib.foo(None, length)
此操作失败,并显示以下错误:
ctypes.ArgumentError:参数1 ::参数必须是ndarray
我可以通过nullptr
吗?
答案 0 :(得分:4)
如果(像我一样)你正在处理多种不同的数组类型,一个稍微好一点的解决方法是自己包装ndpointer
:
import numpy as np
from numpy.ctypeslib import ndpointer
def 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')
答案 1 :(得分:1)
根据eryksun在评论中的出色建议,我将ctypeslib.ndpointer
返回的类型子类化,并实现了重写from_param
。这有点棘手,因为它必须使用类工厂技术来完成,因为ctypeslib.ndpointer
返回的类是由工厂生成的。
我最终得到的代码:
_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)}
)
非常感谢eryksun(一如既往)专家建议。