Les fonctions d'une interface HIDL sont mappées sur des méthodes dans la déclaration de classe C++ IFoo
générée automatiquement. Le nom de chaque fonction reste le même en C++. Les sections suivantes décrivent comment les arguments et les valeurs de retour HIDL sont traduits en C++.
Paramètres de fonction
Les arguments listés dans le fichier .hal
sont mappés sur les types de données C++.
Les arguments qui ne correspondent pas à un type C++ primitif sont transmis par référence const.
Pour chaque fonction HIDL ayant une valeur renvoyée (avec une instruction generates
), la liste des paramètres C++ de cette fonction comporte un argument supplémentaire : une fonction de rappel appelée avec les valeurs renvoyées de la fonction HIDL.
Une exception: Si la clause generates
contient un seul paramètre qui se mappe directement sur une primitive C++, l'élimination du rappel est utilisée (le rappel est supprimé et la valeur de retour est renvoyée à partir de la fonction via une instruction return
normale).
Valeurs de retour de fonction
Les fonctions suivantes ont des valeurs renvoyées.
Erreurs de transport et type de retour
L'instruction generates
peut générer trois types de signatures de fonction:
- Pour une seule valeur renvoyée qui est une primitive C++, la valeur renvoyée
generates
est renvoyée par valeur de la fonction dans un objetReturn<T>
. - Pour les cas plus complexes, la ou les valeurs renvoyées par
generates
sont renvoyées via le paramètre de rappel fourni avec l'appel de fonction lui-même, et la fonction renvoieReturn<void>
. - En l'absence d'instruction
generates
, la fonction renvoieReturn<void>
.
Les appels RPC peuvent parfois rencontrer des erreurs de transport, par exemple lorsque le serveur meurt, lorsque les ressources de transport sont insuffisantes pour effectuer l'appel ou lorsque les paramètres transmis ne permettent pas d'effectuer l'appel (par exemple, en cas d'absence de fonction de rappel requise). Les objets Return
stockent des indications d'erreur de transport ainsi qu'une valeur T
(sauf Return<void>
).
Comme les fonctions côté client et côté serveur ont la même signature, la fonction côté serveur doit renvoyer un type Return
, même si son implémentation ne signale pas d'erreurs de transport. Les objets Return<T>
sont construits avec Return(myTValue)
(ou peuvent être construits implicitement à partir de mTValue
, comme dans les instructions return
) et les objets Return<void>
sont construits avec Void()
.
Les objets Return<T>
sont convertis de manière implicite vers et depuis leur valeur T
. Vous pouvez vérifier si l'objet Return
contient des erreurs de transport en appelant sa méthode isOk()
. Cette vérification n'est pas obligatoire. Toutefois, si une erreur se produit et n'est pas vérifiée au moment de la destruction de l'objet Return
ou d'une tentative de conversion de valeur T
, le processus client est arrêté et une erreur est enregistrée. Si isOk()
indique une erreur de transport ou un échec d'appel en raison d'une erreur logique dans le code du développeur (par exemple, en transmettant nullptr
en tant que rappel synchrone), description()
peut être appelé sur l'objet "Return" pour renvoyer une chaîne adaptée à la journalisation. Dans ce cas, il n'est pas possible de déterminer la quantité de code qui a pu être exécutée sur le serveur à la suite de l'échec de l'appel. La méthode isDeadObject()
est également fournie. Cette méthode indique que !isOk()
est dû au fait que l'objet distant a planté ou n'existe plus. isDeadObject()
implique toujours !isOk()
.
Renvoyer par valeur
Si l'instruction generates
est mappée à une seule primitive C++, aucun paramètre de rappel ne figure dans la liste des paramètres. Au lieu de cela, une implémentation fournit la valeur renvoyée T
dans un objet Return<T>
, qui peut être généré implicitement à partir du type primitif T
. Exemple :
Return<uint32_t> someMethod() { uint32_t return_data = ...; // Compute return_data return return_data; };
La méthode Return<*>::withDefault
est également fournie. Cette méthode fournit une valeur lorsque la valeur renvoyée est !isOk()
.
Cette méthode marque également automatiquement l'objet de retour comme correct afin que le processus client ne soit pas arrêté.
Renvoyer à l'aide du paramètre de rappel
Un rappel peut transmettre la valeur de retour de la fonction HIDL à l'appelant.
Le prototype du rappel est un objet std::function
avec des paramètres (extraits de l'instruction generates
) mappés sur des types C++. Sa valeur renvoyée est nulle. Le rappel lui-même ne renvoie aucune valeur.
La valeur renvoyée par une fonction C++ avec un paramètre de rappel est de type Return<void>
. L'implémentation du serveur n'est responsable que de la valeur renvoyée. Comme les valeurs de retour sont déjà transférées à l'aide du rappel, le paramètre de modèle T
est void
:
Return<void> someMethod(someMethod_cb _cb);
À partir de leur implémentation C++, les implémentations de serveur doivent renvoyer Void()
, qui est une fonction statique intégrée renvoyant un objet Return<void>
. Exemple d'implémentation d'une méthode de serveur avec un paramètre de rappel:
Return<void> someMethod(someMethod_cb _cb) { // Do some processing, then call callback with return data hidl_vec<uint32_t> vec = ... _cb(vec); return Void(); };
Fonctions sans valeur de retour
La signature C++ d'une fonction sans instruction generates
ne comporte pas de paramètre de rappel dans la liste des paramètres. Son type renvoyé est Return<void>.
.
Fonctions à sens unique
Les fonctions marquées avec le mot clé oneway
sont des fonctions asynchrones (les clients ne se bloquent pas lors de leur exécution) et n'ont pas de valeurs renvoyées. La signature C++ d'une fonction oneway
ne comporte pas de paramètre de rappel dans la liste des paramètres, et sa valeur de retour C++ est Return<void>
.