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 traduzidos para C++.

Parâmetros de função

Os argumentos listados no arquivo .hal são mapeados para tipos de dados C++. 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 possui um valor de retorno (possui uma instrução generates ), a lista de parâmetros C++ para essa função possui 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 contém 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 return normal).

Valores de retorno da função

As funções a seguir possuem 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 pelo 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 de função, e a função retorna Return<void> .
  • Pois 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). Os objetos 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 possuem a mesma assinatura, a função do lado do servidor deve retornar um tipo Return mesmo que sua implementação não sinalize erros de transporte. Os 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 os objetos Return<void> são construídos com Void() .

Os 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; entretanto, se ocorrer um erro e não for verificado no momento em que o objeto Return for destruído ou se uma conversão de valor T for tentada, o processo do cliente será eliminado e um erro será registrado. Se isOk() indicar um erro de transporte ou uma falha de chamada devido a um erro lógico no código do desenvolvedor (como passar nullptr como um retorno de chamada síncrono), então description() poderá ser chamado no objeto Return para retornar uma string adequada para registro. Nesses casos, não há como determinar quanto código pode ter sido executado no servidor como resultado da falha na chamada. O método isDeadObject() também é fornecido. Este método indica que !isOk() ocorre porque o objeto remoto travou ou não existe mais. isDeadObject() sempre implica !isOk() .

Retorno por valor

Se a instrução generates mapeada para uma única primitiva C++, nenhum parâmetro de retorno de chamada estará 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() . Este método também marca automaticamente o objeto de retorno como correto para que o processo do cliente não seja eliminado.

Retornar usando 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 é nulo – 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 tipo Return<void> . A implementação do servidor é responsável apenas por fornecer o valor de retorno. Como os valores de retorno já foram transferidos usando o retorno de chamada, o parâmetro do modelo T é void :

Return<void> someMethod(someMethod_cb _cb);

A partir 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 implementação típica de método de servidor com 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

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> .