Installs handlers for event callbacks.

    Corresponds to viInstallHandler function of the VISA library.

    :param library: the visa library wrapped by ctypes.
    :param session: Unique logical identifier to a session.
    :param event_type: Logical event identifier.
    :param handler: Interpreted as a valid reference to a handler to be installed by a client application.
    :param user_handle: A value specified by an application that can be used for identifying handlers
                        uniquely for an event type. Can be a regular python object (int, float, str, list
                        of floats or ints) or a ctypes object.
    :returns: a handler descriptor which consists of three elements:
             - handler (a python callable)
             - user handle (a ctypes object)
             - ctypes handler (ctypes object wrapping handler)
             and return value of the library call.
    :rtype: int, :class:`pyvisa.constants.StatusCode`

def install_handler(library, session, event_type, handler, user_handle):
    """Installs handlers for event callbacks.

    Corresponds to viInstallHandler function of the VISA library.

    :param library: the visa library wrapped by ctypes.
    :param session: Unique logical identifier to a session.
    :param event_type: Logical event identifier.
    :param handler: Interpreted as a valid reference to a handler to be installed by a client application.
    :param user_handle: A value specified by an application that can be used for identifying handlers
                        uniquely for an event type. Can be a regular python object (int, float, str, list
                        of floats or ints) or a ctypes object.
    :returns: a handler descriptor which consists of three elements:
             - handler (a python callable)
             - user handle (a ctypes object)
             - ctypes handler (ctypes object wrapping handler)
             and return value of the library call.
    :rtype: int, :class:`pyvisa.constants.StatusCode`
    """
    if user_handle is None:
        converted_user_handle = None
    else:
        if isinstance(user_handle, int):
            converted_user_handle = c_long(user_handle)
        elif isinstance(user_handle, float):
            converted_user_handle = c_double(user_handle)
        elif isinstance(user_handle, str):
            converted_user_handle = create_string_buffer(user_handle)
        elif isinstance(user_handle, list):
            for element in user_handle:
                if not isinstance(element, int):
                    converted_user_handle = \
                        (c_double * len(user_handle))(tuple(user_handle))
                    break
            else:
                converted_user_handle = \
                    (c_long * len(user_handle))(*tuple(user_handle))
        else:
            try:
                # check if it is already a ctypes
                byref(user_handle)
                converted_user_handle = user_handle
            except TypeError:
                raise TypeError("Type not allowed as user handle: %s" % type(user_handle))

    set_user_handle_type(library, converted_user_handle)
    converted_handler = ViHndlr(handler)
    if user_handle is None:
        ret = library.viInstallHandler(session, event_type, converted_handler, None)
    else:
        ret = library.viInstallHandler(session, event_type, converted_handler,
                                       byref(converted_user_handle))

    return handler, converted_user_handle, converted_handler, ret