Fonctions

Les fonctions d'une interface HIDL sont mappées aux méthodes dans la déclaration de classe IFoo C++ générée automatiquement. Le nom de chaque fonction reste le même en C++ ; les sections suivantes décrivent comment les arguments HIDL et les valeurs de retour sont traduits en C++.

Paramètres de fonction

Les arguments répertoriés dans le fichier .hal correspondent aux 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 qui a une valeur de retour (une instruction generates ), la liste de paramètres C++ de cette fonction comporte un argument supplémentaire : une fonction de rappel qui est appelée avec les valeurs de retour de la fonction HIDL. Il y a une exception : si la clause generates contient un seul paramètre qui correspond directement à une primitive C++, l'élision de rappel est utilisée (le rappel est supprimé et la valeur de retour est renvoyée par la fonction via une instruction return normale).

Valeurs de retour de la fonction

Les fonctions suivantes ont des valeurs de retour.

Erreurs de transport et type de retour

L'instruction generates peut donner lieu à trois types de signatures de fonction :

  • Pour une seule valeur de retour qui est une primitive C++, la valeur de retour generates est renvoyée par valeur de la fonction dans un objet Return<T> .
  • Pour les cas plus compliqués, la ou les valeurs de retour 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> .
  • Car lorsqu’aucune instruction generates n’existe, la fonction renvoie Return<void> .

Les appels RPC peuvent occasionnellement rencontrer des erreurs de transport, par exemple lorsque le serveur tombe en panne, lorsque les ressources de transport sont insuffisantes pour terminer l'appel, ou lorsque les paramètres transmis ne permettent pas de terminer l'appel (comme par exemple l'absence d'une 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 implicitement construits à partir de mTValue , comme dans les instructions return ) et les objets Return<void> sont construits avec Void() .

Les objets Return<T> ont une conversion implicite vers et depuis leur valeur T L'objet Return peut être vérifié pour les erreurs de transport en appelant sa méthode isOk() . Cette vérification n'est pas obligatoire ; cependant, si une erreur se produit et n'est pas vérifiée au moment où l'objet Return est détruit, ou si une conversion de valeur T est tentée, le processus client sera arrêté et une erreur enregistrée. Si isOk() indique une erreur de transport ou un échec d'appel dû à une erreur logique dans le code du développeur (comme le passage nullptr comme rappel synchrone), alors description() peut être appelée sur l'objet Return pour renvoyer une chaîne adaptée à la journalisation. Dans de tels cas, il n'existe aucun moyen de déterminer la quantité de code qui a pu être exécuté 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 est tombé en panne ou n'existe plus. isDeadObject() implique toujours !isOk() .

Retour par valeur

Si l'instruction generates correspond à 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 de retour T dans un objet Return<T> , qui peut être implicitement généré à partir du type primitif T . Par 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 dans les cas où la valeur de retour est !isOk() . Cette méthode marque également automatiquement l'objet de retour comme étant correct afin que le processus client ne soit pas tué.

Retour en utilisant le 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 (tirés de l'instruction generates ) mappés aux types C++. Sa valeur de retour est void : le rappel lui-même ne renvoie pas de valeur.

La valeur de retour d'une fonction C++ avec un paramètre de rappel est de type Return<void> . L'implémentation du serveur est uniquement responsable de fournir la valeur de retour. Comme les valeurs de retour sont déjà transférées à l'aide du rappel, le paramètre du 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 en ligne renvoyant un objet Return<void> . Exemple d'implémentation typique d'une méthode 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 valeurs de retour

La signature C++ d'une fonction sans instruction generates n'aura pas de paramètre de rappel dans la liste des paramètres. Son type de retour sera Return<void>.

Fonctions à sens unique

Les fonctions marquées avec le mot-clé oneway sont des fonctions asynchrones (les clients ne bloqueront pas leur exécution) et n'ont pas de valeurs de retour. La signature C++ d'une fonction oneway n'aura pas de paramètre de rappel dans la liste des paramètres et sa valeur de retour C++ sera Return<void> .