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 oggettogenerates
.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 restituisceReturn<void>
. - Se non esiste un'istruzione
generates
, la funzione restituisceReturn<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>
.