Fonctions

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 objet Return<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 renvoie Return<void>.
  • En l'absence d'instruction generates, la fonction renvoie Return<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>.