Funciones

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

Parámetros de la función

Los argumentos que se enumeran en el archivo .hal se asignan a 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 que se muestra (tiene una sentencia generates), la lista de parámetros de C++ para esa función tiene un argumento adicional: una función de devolución de llamada a la que se llama con los valores que se muestran 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 eliisión de devolución de llamada (se quita la devolución de llamada y se muestra el valor que se muestra desde la función a través de una sentencia return normal).

Valores que devuelven las funciones

Las siguientes funciones tienen valores que se muestran.

Errores de transporte y tipo de devolución

La sentencia generates puede generar tres tipos de firmas de función:

  • Para un solo valor que sea una primitiva de C++, el valor que se muestra de generates se muestra por valor de la función en un objeto Return<T>.
  • En casos más complejos, los valores que muestra generates se muestran a través del parámetro de devolución de llamada proporcionado con la llamada a la función, y la función muestra Return<void>.
  • Cuando no existe una sentencia generates, la función muestra Return<void>.

En ocasiones, las llamadas a RPC pueden encontrar errores de transporte, p.ej., cuando falla el servidor, cuando los recursos de transporte no son suficientes para completar la llamada o cuando los parámetros pasados no permiten completar la llamada (por ejemplo, falta una función de devolución de llamada obligatoria). Los objetos Return almacenan indicaciones de errores de transporte, así como un valor T (excepto Return<void>).

Como las funciones del cliente y del servidor tienen la misma firma, la función del servidor debe mostrar un tipo Return, aunque su implementación no indique errores de transporte. Los objetos Return<T> se construyen con Return(myTValue) (o se pueden construir de forma implícita a partir de mTValue, como en las sentencias 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. Para verificar si el objeto Return tiene errores de transporte, llama a su método isOk(). Esta verificación no es obligatoria. Sin embargo, si se produce un error y no se verifica cuando se destruye el objeto Return o se intenta una conversión de valor T, se finalizará el proceso del cliente y se registrará un error. Si isOk() indica un error de transporte o una falla de llamada debido a un error de lógica en el código del desarrollador (como pasar nullptr como una devolución de llamada síncrona), se puede llamar a description() en el objeto Return para mostrar una cadena adecuada para el registro. En esos 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 falló o ya no existe. isDeadObject() siempre implica !isOk().

Mostrar por valor

Si la sentencia generates se asigna a una sola 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 que se muestra T en un objeto Return<T>, que se puede generar de forma implícita 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 que se muestra es !isOk(). Este método también marca automáticamente el objeto que se muestra como correcto para que no se cancele el proceso del cliente.

Cómo mostrar un resultado con el parámetro de devolución de llamada

Una devolución de llamada puede pasar el valor de retorno de la función HIDL al llamador. El prototipo de la devolución de llamada es un objeto std::function con parámetros (tomados de la sentencia generates) asignados a tipos de C++. Su valor que se muestra es nulo; la devolución de llamada en sí no muestra ningún valor.

El valor que se muestra 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 solo es responsable de proporcionar el valor que se muestra. Como los valores que se muestran ya se transfieren con la devolución de llamada, el parámetro de plantilla T es void:

Return<void> someMethod(someMethod_cb _cb);

Desde su implementación en C++, las implementaciones del servidor deben mostrar Void(), que es una función intercalada estática que muestra 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 devueltos

La firma de C++ de una función sin una sentencia generates no tendrá un parámetro de devolución de llamada en la lista de parámetros. Su tipo de datos que se mostrará 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 que se muestran. 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>.