As funções em uma interface HIDL são mapeadas para métodos na declaração de classe C++
IFoo
gerada automaticamente. O nome de cada função permanece o
mesmo em C++; as seções a seguir descrevem como os argumentos e os valores de retorno
do HIDL são traduzidos para C++.
Parâmetros de função
Os argumentos listados no arquivo .hal
são mapeados para tipos de dados C++.
Os argumentos que não são mapeados para um tipo primitivo do C++ são transmitidos por referência
const.
Para cada função HIDL que tenha um valor de retorno (tenha uma instrução
generates
), a lista de parâmetros C++ para essa função tem um argumento adicional:
uma função de callback 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++, o callback
será omitido. O callback é removido e o valor de retorno é
retornado da função por uma instrução 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 é uma primitiva C++, o
valor de retorno
generates
é retornado pelo valor da função em um objetoReturn<T>
. - Para casos mais complicados, os valores de retorno
generates
são retornados pelo parâmetro de callback fornecido com a chamada de função, e a função retornaReturn<void>
. - Quando nenhuma instrução
generates
existe, a função retornaReturn<void>
.
As chamadas RPC podem ocasionalmente encontrar erros de transporte, por exemplo, quando o servidor
morre, quando os recursos de transporte são insuficientes para concluir a chamada ou quando
os parâmetros transmitidos não permitem concluir a chamada (como a ausência de uma
função de callback obrigatória). Os objetos Return
armazenam indicações de erro de transporte
e um valor T
(exceto
Return<void>
).
Como as funções do lado do cliente e do servidor têm a mesma assinatura, a função do lado do servidor precisa retornar um tipo Return
, mesmo que a 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
com 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 para e de
seu valor T
. É possível verificar se o objeto Return
tem
erros de transporte chamando o método isOk()
dele. Essa verificação não é
necessária. No entanto, se um erro ocorrer e não for verificado quando o
objeto Return
for destruído ou se 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
lógico no código do desenvolvedor (como transmitir nullptr
como um callback
síncrono), description()
poderá ser chamado no objeto de retorno 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
chamada com falha. O método isDeadObject()
também é fornecido. Esse
método indica que !isOk()
ocorre porque o objeto remoto
trava ou não existe mais. isDeadObject()
sempre implica
!isOk()
.
Retornar por valor
Se a instrução generates
mapeia para uma única primitiva C++, nenhum
parâmetro de callback 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 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. Esse
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 bom, para que o processo
do cliente não seja encerrado.
Retornar usando o parâmetro de callback
Um callback pode transmitir o valor de retorno da função HIDL de volta ao autor da chamada.
O protótipo do callback é um objeto std::function
com
parâmetros (extraídos da instrução generates
) mapeados para tipos
C++. O valor de retorno é nulo. O callback em si não retorna um valor.
O valor de retorno de uma função C++ com um parâmetro de callback 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á foram transferidos
usando o callback, o parâmetro de modelo T
é void
:
Return<void> someMethod(someMethod_cb _cb);
A partir da implementação em C++, as implementações do servidor precisam retornar
Void()
, que é uma função inline estática que retorna um
objeto Return<void>
. Exemplo de implementação de um método de servidor
típico com um parâmetro de callback:
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 callback na lista de parâmetros. O 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 são bloqueados na execução) e não têm valores de
retorno. A assinatura C++ de uma função oneway
não terá um
parâmetro de callback na lista de parâmetros, e o valor de retorno do C++ será
Return<void>
.