Funzioni

Le funzioni in un'interfaccia HIDL sono mappate ai metodi nella dichiarazione della classe C++ IFoo generata automaticamente. Il nome di ogni funzione rimane invariato in C++; le sezioni seguenti descrivono come gli argomenti e i valori di ritorno HIDL vengono tradotti in C++.

Parametri di funzione

Gli argomenti elencati nel file .hal vengono mappati ai tipi di dati C++. Gli argomenti che non mappano a un tipo C++ primitivo vengono passati per riferimento costante.

Per ogni funzione HIDL che ha un valore restituito (ha un'istruzione generates), l'elenco dei parametri C++ per quella funzione ha un argomento aggiuntivo: una funzione di callback chiamata con i valori restituiti della funzione HIDL. Esiste un'eccezione: se la clausola generates contiene un singolo parametro che mappa direttamente a un elemento primitivo C++, viene utilizzata l'elisione del callback (il callback viene rimosso e il valore restituito viene restituito dalla funzione tramite una normale istruzione return).

Valori restituiti dalle funzioni

Le seguenti funzioni hanno valori restituiti.

Errori di trasporto e tipo di reso

L'istruzione generates può generare tre tipi di firme di funzione:

  • Per un solo valore restituito che è un tipo primitivo C++, il valore restituito generates viene restituito per valore dalla funzione in un oggetto generates.Return<T>
  • Per casi più complicati, i valori restituiti generates vengono riportati tramite il parametro di callback fornito con la chiamata della funzione stessa e la funzione restituisce Return<void>.
  • Se non esiste un'istruzione generates, la funzione restituisce Return<void>.

A volte le chiamate RPC possono riscontrare errori di trasporto, ad esempio quando il server si arresta, quando le risorse di trasporto non sono sufficienti per completare la chiamata o quando i parametri passati non consentono di completare la chiamata (ad esempio se manca una funzione di callback obbligatoria). Gli oggetti Return memorizzano indicazioni di errori di trasporto nonché un valore T (tranne Return<void>).

Poiché le funzioni lato client e lato server hanno la stessa firma, la funzione lato server deve restituire un tipo Return anche se la sua implementazione non segnala errori di trasporto. Gli oggetti Return<T> vengono costruiti con Return(myTValue) (o possono essere costruiti implicitamente da mTValue, ad esempio nelle istruzioni return) e gli oggetti Return<void> vengono costruiti con Void().

Gli oggetti Return<T> hanno una conversione implicita verso e da il loro valore T. È possibile verificare la presenza di errori di trasporto nell'oggetto Return chiamando il relativo metodo isOk(). Questo controllo non è obbligatorio. Tuttavia, se si verifica un errore e non viene controllato prima dell'eliminazione dell'oggetto Return o viene tentata la conversione di un valore T, il processo client verrà interrotto e verrà registrato un errore. Se isOk() indica un errore di trasporto o un errore di chiamata a causa di un errore logico nel codice sviluppatore (ad esempio il passaggio di nullptr come callback sincrono), description() può essere chiamato nell'oggetto Return per restituire una stringa adatta per la registrazione. In questi casi, non è possibile determinare quanto codice potrebbe essere stato eseguito sul server a seguito della chiamata non riuscita. È fornito anche il metodo isDeadObject(). Questo metodo indica che !isOk() si verifica perché l'oggetto remoto ha avuto un arresto anomalo o non esiste più. isDeadObject() implica sempre !isOk().

Restituire per valore

Se l'istruzione generates mappa a una singola primitiva C++, nell'elenco dei parametri non è presente alcun parametro callback. Invece, un'implementazione fornisce il valore restituito T in un oggetto Return<T>, che può essere generato implicitamente dal tipo primitivo T. Per esempio:

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

È fornito anche il metodo Return<*>::withDefault. Questo metodo fornisce un valore nei casi in cui il valore restituito è !isOk(). Questo metodo contrassegna automaticamente anche l'oggetto restituito come corretto, in modo che il processo del client non venga interrotto.

Ritorna utilizzando il parametro di callback

Un callback può restituire il valore restituito della funzione HIDL al chiamante. Il prototipo del callback è un oggetto std::function con parametri (riportati dall'istruzione generates) mappati ai tipi C++. Il valore restituito è nullo: il callback stesso non restituisce un valore.

Il valore restituito di una funzione C++ con un parametro di callback è di tipo Return<void>. L'implementazione del server è responsabile solo dell'indicazione del valore restituito. Poiché i valori restituiti sono già trasferiti tramite il callback, il parametro del modello T è void:

Return<void> someMethod(someMethod_cb _cb);

Dall'implementazione C++, le implementazioni del server devono restituire Void(), che è una funzione in linea statica che restituisce un Return<void> oggetto. Esempio di una tipica implementazione del metodo del server con un parametro di 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();
};

Funzioni senza valori restituiti

La firma C++ di una funzione senza un'istruzione generates non avrà un parametro di callback nell'elenco dei parametri. Il tipo di ritorno sarà Return<void>.

Funzioni unidirezionali

Le funzioni contrassegnate con la parola chiave oneway sono funzioni asincrone (i client non si bloccano durante la loro esecuzione) e non hanno valori di ritorno. La firma C++ di una funzione oneway non avrà un parametro callback nell'elenco dei parametri e il relativo valore restituito in C++ sarà Return<void>.