Funções

As funções em uma interface HIDL são mapeadas para métodos na declaração de classe IFoo C++ gerada automaticamente. O nome de cada função permanece o mesmo em C++; as seções a seguir descrevem como os argumentos HIDL e os valores de retorno são convertidos para C++.

Parâmetros de função

Os argumentos listados no mapa de arquivo .hal para tipos de dados C++. Os argumentos que não são mapeados para um tipo C++ primitivo são passados ​​por referência const.

Para cada função HIDL que tem um valor de retorno (tem uma instrução generates ), a lista de parâmetros C++ para essa função tem um argumento adicional: uma função de retorno de chamada que é chamada com os valores de retorno da função HIDL. Há uma exceção : se a cláusula generates contiver um único parâmetro que mapeia diretamente para uma primitiva C++, a elisão de retorno de chamada é usada (o retorno de chamada é removido e o valor de retorno é retornado da função por meio de uma instrução de return normal).

Valores de retorno da função

As funções a seguir têm valores de retorno.

Erros de transporte e tipo de retorno

A instrução generates pode resultar em três tipos de assinaturas de função:

  • Para apenas um valor de retorno que é um primitivo C++, o valor de retorno generates é retornado por valor da função em um objeto Return<T> .
  • Para casos mais complicados, os valores de retorno generates são retornados por meio do parâmetro de retorno de chamada fornecido com a própria chamada da função, e a função retorna Return<void> .
  • Para quando não existe nenhuma instrução generates , a função retorna Return<void> .

Chamadas RPC podem ocasionalmente encontrar erros de transporte, por exemplo, quando o servidor morre, quando os recursos de transporte são insuficientes para completar a chamada ou quando os parâmetros passados ​​não permitem completar a chamada (como falta de uma função de retorno de chamada necessária). Objetos de Return armazenam indicações de erro de transporte, bem como um valor T (exceto Return<void> ).

Como as funções do lado do cliente e do lado do servidor têm a mesma assinatura, a função do lado do servidor deve retornar um tipo de Return mesmo que sua implementação não indique erros de transporte. Objetos Return<T> são construídos com Return(myTValue) (ou podem ser construídos implicitamente a partir de mTValue , como em instruções return ) e objetos Return<void> são construídos com Void() .

Objetos Return<T> têm conversão implícita de e para seu valor T O objeto Return pode ser verificado quanto a erros de transporte chamando seu método isOk() . Esta verificação não é necessária; no entanto, se ocorrer um erro e não for verificado no momento em que o objeto Return for destruído, ou uma conversão de valor T for tentada, o processo do cliente será encerrado e um erro será registrado. Se isOk() indicar um erro de transporte ou uma falha de chamada devido a um erro de lógica no código do desenvolvedor (como passar nullptr como um retorno de chamada síncrono), então description() pode ser chamado no objeto Return para retornar uma string adequada para log. Nesses casos, não há como determinar quanto código pode ter sido executado no servidor como resultado da chamada com falha. O método isDeadObject() também é fornecido. Este método indica que !isOk() é porque o objeto remoto travou ou não existe mais. isDeadObject() sempre implica !isOk() .

Retorno por valor

Se a instrução generates mapas para uma única primitiva C++, nenhum parâmetro de retorno de chamada está na lista de parâmetros. Em vez disso, uma implementação fornece o valor de retorno T em um objeto Return<T> , que pode ser gerado implicitamente a partir do tipo primitivo T . Por exemplo:

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

O método Return<*>::withDefault também é fornecido. Este método fornece um valor nos casos em que o valor de retorno é !isOk() . Esse método também marca automaticamente o objeto de retorno como ok para que o processo do cliente não seja encerrado.

Retornar usando o parâmetro de retorno de chamada

Um retorno de chamada pode passar o valor de retorno da função HIDL de volta ao chamador. O protótipo do retorno de chamada é um objeto std::function com parâmetros (retirados da instrução generates ) mapeados para tipos C++. Seu valor de retorno é void — o retorno de chamada em si não retorna um valor.

O valor de retorno de uma função C++ com um parâmetro de retorno de chamada tem o tipo Return<void> . A implementação do servidor é responsável apenas por fornecer o valor de retorno. Como os valores de retorno já são transferidos usando o callback, o parâmetro T template é void :

Return<void> someMethod(someMethod_cb _cb);

De sua implementação em C++, as implementações de servidor devem retornar Void() , que é uma função embutida estática que retorna um objeto Return<void> . Exemplo de uma implementação típica de método de servidor com um parâmetro de retorno de chamada:

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

Funções sem valores de retorno

A assinatura C++ de uma função sem uma instrução generates não terá um parâmetro de retorno de chamada na lista de parâmetros. Seu tipo de retorno será Return<void>.

Funções unidirecionais

As funções marcadas com a palavra-chave oneway são funções assíncronas (os clientes não bloquearão sua execução) e não possuem valores de retorno. A assinatura C++ de uma função oneway não terá um parâmetro de retorno de chamada na lista de parâmetros e seu valor de retorno C++ será Return<void> .