Funciones

Las funciones en una interfaz HIDL se asignan a métodos en la declaración de clase IFoo C++ generada automáticamente. El nombre de cada función sigue siendo el mismo en C++; las siguientes secciones describen cómo los argumentos HIDL y los valores devueltos se traducen a C++.

Parámetros de función

Los argumentos enumerados en el archivo .hal se asignan a los tipos de datos de C++. Los argumentos que no se asignan a un tipo C++ primitivo se pasan por referencia const.

Para cada función HIDL que tiene un valor devuelto (tiene una declaración generates ), la lista de parámetros de C++ para esa función tiene un argumento adicional: una función de devolución de llamada que se llama con los valores devueltos de la función HIDL. Hay una excepción : si la cláusula generates contiene un solo parámetro que se asigna directamente a una primitiva de C++, se usa la elisión de devolución de llamada (la devolución de llamada se elimina y el valor de retorno se devuelve desde la función a través de una declaración de return normal).

Valores de retorno de la función

Las siguientes funciones tienen valores de retorno.

Errores de transporte y tipo de devolución

La declaración generates puede dar como resultado tres tipos de firmas de funciones:

  • Para un solo valor devuelto que es un primitivo de C++, el valor devuelto generates se devuelve por valor de la función en un objeto Return<T> .
  • Para casos más complicados, los valores de devolución generates se devuelven a través del parámetro de devolución de llamada proporcionado con la llamada de función en sí, y la función devuelve Return<void> .
  • Porque cuando no existe una declaración generates , la función devuelve Return<void> .

Las llamadas RPC ocasionalmente pueden encontrar errores de transporte, por ejemplo, cuando el servidor muere, cuando los recursos de transporte son insuficientes para completar la llamada o cuando los parámetros pasados ​​no permiten completar la llamada (como falta de una función de devolución de llamada requerida). Los objetos devueltos almacenan indicaciones de errores de transporte, así como un valor T (excepto Return Return<void> ).

Como las funciones del lado del cliente y del lado del servidor tienen la misma firma, la función del lado del servidor debe devolver un tipo de Return aunque su implementación no señale errores de transporte. Los objetos Return<T> se construyen con Return(myTValue) (o se pueden construir implícitamente a partir de mTValue , como en declaraciones de return ) y los objetos Return<void> se construyen con Void() .

Los objetos Return<T> tienen una conversión implícita hacia y desde su valor T El objeto Return se puede comprobar en busca de errores de transporte llamando a su método isOk() . Esta verificación no es necesaria; sin embargo, si se produce un error y no se comprueba antes de que se destruya el objeto Return o se intente una conversión de valor T , el proceso del cliente se cancelará y se registrará un error. Si isOk() indica un error de transporte o una falla en la llamada debido a un error lógico en el código del desarrollador (como pasar nullptr como una devolución de llamada síncrona), entonces se puede llamar a description() en el objeto Return para devolver una cadena adecuada para el registro. En tales casos, no hay forma de determinar cuánto código se pudo haber ejecutado en el servidor como resultado de la llamada fallida. También se proporciona el método isDeadObject() . Este método indica que !isOk() se debe a que el objeto remoto se bloqueó o ya no existe. isDeadObject() siempre implica !isOk() .

Retorno por valor

Si la declaración generates se asigna a una única primitiva de C++, no hay ningún parámetro de devolución de llamada en la lista de parámetros. En su lugar, una implementación proporciona el valor de retorno T en un objeto Return<T> , que se puede generar implícitamente a partir del tipo primitivo T . Por ejemplo:

Return<uint32_t> someMethod() {
    uint32_t return_data = ...; // Compute return_data
    return return_data;
};

También se proporciona el método Return<*>::withDefault . Este método proporciona un valor en los casos en que el valor devuelto es !isOk() . Este método también marca automáticamente el objeto de devolución como correcto para que el proceso del cliente no se elimine.

Devolver usando el parámetro de devolución de llamada

Una devolución de llamada puede devolver el valor de retorno de la función HIDL a la persona que llama. El prototipo de la devolución de llamada es un objeto std::function con parámetros (tomados de la declaración generates ) asignados a tipos de C++. Su valor devuelto es nulo: la devolución de llamada en sí no devuelve ningún valor.

El valor de retorno de una función de C++ con un parámetro de devolución de llamada tiene el tipo Return<void> . La implementación del servidor es responsable solo de proporcionar el valor de retorno. Como los valores de retorno ya se transfieren mediante la devolución de llamada, el parámetro de la plantilla T es void :

Return<void> someMethod(someMethod_cb _cb);

Desde su implementación en C++, las implementaciones del servidor deberían devolver Void() , que es una función estática en línea que devuelve un objeto Return<void> . Ejemplo de una implementación típica de un método de servidor con un parámetro de devolución de llamada:

Return<void> someMethod(someMethod_cb _cb) {
    // Do some processing, then call callback with return data
    hidl_vec<uint32_t> vec = ...
    _cb(vec);
    return Void();
};

Funciones sin valores de retorno

La firma C++ de una función sin una declaración generates no tendrá un parámetro de devolución de llamada en la lista de parámetros. Su tipo de devolución será Return<void>.

Funciones unidireccionales

Las funciones marcadas con la palabra clave oneway son funciones asíncronas (los clientes no se bloquearán en su ejecución) y no tienen valores de retorno. La firma de C++ de una función oneway no tendrá un parámetro de devolución de llamada en la lista de parámetros y su valor de retorno de C++ será Return<void> .