'ctypes implementation of imperative invoke wrapper'

def __call__(self, *args, **kwargs):

    out = kwargs.pop('out', None)
    if (out is not None):
        original_output = out
        if isinstance(out, NDArrayBase):
            out = (out,)
        num_output = ctypes.c_int(len(out))
        output_vars = c_array(NDArrayHandle, [i.handle for i in out])
        output_vars = ctypes.cast(output_vars, ctypes.POINTER(NDArrayHandle))
    else:
        original_output = None
        output_vars = ctypes.POINTER(NDArrayHandle)()
        num_output = ctypes.c_int(0)
    if kwargs:
        raise TypeError(('CachedOp.__call__    got    unexpected    keyword    argument(s):    ' + ',    '.join(kwargs.keys())))
    check_call(_LIB.MXInvokeCachedOp(self.handle, ctypes.c_int(len(args)), c_array(NDArrayHandle, [arr.handle for arr in args]), ctypes.byref(num_output), ctypes.byref(output_vars)))
    if (original_output is not None):
        return original_output
    if (num_output.value == 1):
        return _ndarray_cls(ctypes.cast(output_vars[0], NDArrayHandle))
    else:
        return [_ndarray_cls(ctypes.cast(output_vars[i], NDArrayHandle)) for i in range(num_output.value)]
