Funktionen

Funktionen in einer HIDL-Schnittstelle werden Methoden in der automatisch generierten IFoo-C++-Klassendeklaration zugeordnet. Der Name jeder Funktion bleibt in C++ unverändert. In den folgenden Abschnitten wird beschrieben, wie HIDL-Argumente und Rückgabewerte in C++ übersetzt werden.

Funktionsparameter

Die in der Datei .hal aufgeführten Argumente werden C++-Datentypen zugeordnet. Argumente, die keinem primitiven C++-Typ zugeordnet werden, werden per const-Referenz übergeben.

Für jede HIDL-Funktion mit einem Rückgabewert (generates-Anweisung) enthält die C++-Parameterliste für diese Funktion ein zusätzliches Argument: eine Callback-Funktion, die mit den Rückgabewerten der HIDL-Funktion aufgerufen wird. Es gibt eine Ausnahme: Wenn die generates-Klausel einen einzelnen Parameter enthält, der direkt einem C++-Primitiven zugeordnet ist, wird die Callback-Elision verwendet. Der Callback wird entfernt und der Rückgabewert wird über eine normale return-Anweisung aus der Funktion zurückgegeben.

Rückgabewerte von Funktionen

Die folgenden Funktionen haben Rückgabewerte.

Transportfehler und Rückgabetyp

Die generates-Anweisung kann drei Arten von Funktionssignaturen ergeben:

  • Wenn nur ein Rückgabewert ein C++-Primitiv ist, wird der Rückgabewert generates von der Funktion in einem Return<T>-Objekt zurückgegeben.
  • In komplexeren Fällen werden die Rückgabewerte von generates über den Callback-Parameter zurückgegeben, der mit dem Funktionsaufruf selbst bereitgestellt wird. Die Funktion gibt dann Return<void> zurück.
  • Wenn keine generates-Anweisung vorhanden ist, gibt die Funktion Return<void> zurück.

Bei RPC-Aufrufen können gelegentlich Transportfehler auftreten, z. B. wenn der Server ausfällt, die Transportressourcen nicht ausreichen, um den Aufruf abzuschließen, oder die übergebenen Parameter den Aufruf nicht zulassen (z. B. wenn eine erforderliche Rückruffunktion fehlt). Return-Objekte speichern Transportfehlerhinweise sowie einen T-Wert (außer Return<void>).

Da die client- und serverseitigen Funktionen dieselbe Signatur haben, muss die serverseitige Funktion einen Return-Typ zurückgeben, auch wenn ihre Implementierung keine Transportfehler signalisiert. Return<T>-Objekte werden mit Return(myTValue) erstellt (oder können implizit aus mTValue erstellt werden, z. B. in return-Anweisungen) und Return<void>-Objekte werden mit Void() erstellt.

Für Return<T>-Objekte erfolgt eine implizite Umwandlung in und aus ihrem T-Wert. Das Return-Objekt kann auf Transportfehler geprüft werden, indem die Methode isOk() aufgerufen wird. Diese Prüfung ist nicht erforderlich. Wenn jedoch ein Fehler auftritt und nicht geprüft wird, bis das Return-Objekt zerstört wird, oder eine T-Wertumwandlung versucht wird, wird der Clientprozess beendet und ein Fehler protokolliert. Wenn isOk() einen Transportfehler oder einen Aufruffehler aufgrund eines Logikfehlers im Entwicklercode angibt (z. B. wenn nullptr als synchroner Rückruf übergeben wird), kann description() auf das Rückgabeobjekt aufgerufen werden, um einen String zurückzugeben, der sich zum Logging eignet. In solchen Fällen lässt sich nicht feststellen, wie viel Code auf dem Server aufgrund des fehlgeschlagenen Aufrufs ausgeführt wurde. Die Methode isDeadObject() wird ebenfalls bereitgestellt. Diese Methode gibt an, dass !isOk() auftritt, weil das Remoteobjekt abgestürzt ist oder nicht mehr vorhanden ist. isDeadObject() impliziert immer !isOk().

Nach Wert zurückgeben

Wenn die generates-Anweisung einem einzelnen C++-Primitiven zugeordnet ist, ist in der Parameterliste kein Rückrufparameter enthalten. Stattdessen stellt eine Implementierung den Rückgabewert T in einem Return<T>-Objekt bereit, das implizit aus dem primitiven Typ T generiert werden kann. Beispiel:

Return<uint32_t> someMethod() {
    uint32_t return_data = ...; // Compute return_data
    return return_data;
};

Die Methode Return<*>::withDefault wird ebenfalls bereitgestellt. Diese Methode liefert einen Wert, wenn der Rückgabewert !isOk() ist. Bei dieser Methode wird das Rückgabeobjekt außerdem automatisch als in Ordnung markiert, damit der Clientprozess nicht beendet wird.

Über den Callback-Parameter zurückgeben

Ein Callback kann den Rückgabewert der HIDL-Funktion an den Aufrufer zurückgeben. Der Prototyp des Callbacks ist ein std::function-Objekt mit Parametern (aus der generates-Anweisung), die C++-Typen zugeordnet sind. Der Rückgabewert ist ungültig – der Callback selbst gibt keinen Wert zurück.

Der Rückgabewert einer C++-Funktion mit einem Callback-Parameter hat den Typ Return<void>. Die Serverimplementierung ist nur für die Bereitstellung des Rückgabewerts verantwortlich. Da die Rückgabewerte bereits über den Callback übertragen werden, ist der Vorlagenparameter T void:

Return<void> someMethod(someMethod_cb _cb);

Serverimplementierungen sollten Void() zurückgeben, eine statische Inline-Funktion, die ein Return<void>-Objekt zurückgibt. Beispiel für eine typische Servermethodenimplementierung mit einem Callback-Parameter:

Return<void> someMethod(someMethod_cb _cb) {
    // Do some processing, then call callback with return data
    hidl_vec<uint32_t> vec = ...
    _cb(vec);
    return Void();
};

Funktionen ohne Rückgabewert

Die C++-Signatur einer Funktion ohne generates-Anweisung enthält keinen Callback-Parameter in der Parameterliste. Der Rückgabetyp ist Return<void>..

Einwegfunktionen

Funktionen, die mit dem Keyword oneway gekennzeichnet sind, sind asynchrone Funktionen (Clients werden bei ihrer Ausführung nicht blockiert) und haben keine Rückgabewerte. Die C++-Signatur einer oneway-Funktion enthält keinen Rückrufparameter in der Parameterliste und ihr C++-Rückgabewert ist Return<void>.