Le funzioni in un'interfaccia HIDL vengono mappate ai metodi nella dichiarazione della classe IFoo
C++ generata automaticamente. Il nome di ciascuna funzione rimane lo stesso in C++; le sezioni seguenti descrivono come gli argomenti HIDL e i valori restituiti vengono tradotti in C++.
Parametri di funzione
Gli argomenti elencati nel file .hal
vengono mappati ai tipi di dati C++. Gli argomenti che non corrispondono a un tipo C++ primitivo vengono passati tramite riferimento const.
Per ogni funzione HIDL che ha un valore restituito (ha un'istruzione generates
), l'elenco di parametri C++ per quella funzione ha un argomento aggiuntivo: una funzione di callback che viene chiamata con i valori restituiti della funzione HIDL. C'è un'eccezione : se la clausola generates
contiene un singolo parametro che si associa direttamente a una primitiva 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 dalla funzione
Le seguenti funzioni hanno valori restituiti.
Errori di trasporto e tipologia di reso
L'istruzione generates
può risultare in tre tipi di firme di funzione:
- Per un solo valore restituito che è una primitiva C++, il valore restituito
generates
viene restituito in base al valore dalla funzione in un oggettoReturn<T>
. - Per i casi più complicati, i valori restituiti
generates
vengono restituiti tramite il parametro callback fornito con la chiamata alla funzione stessa e la funzione restituisceReturn<void>
. - Infatti, quando non esiste alcuna istruzione
generates
, la funzione restituisceReturn<void>
.
Le chiamate RPC possono occasionalmente riscontrare errori di trasporto, ad esempio quando il server muore, quando le risorse di trasporto non sono sufficienti per completare la chiamata o quando i parametri passati non consentono il completamento della chiamata (ad esempio manca una funzione di callback richiesta). Gli oggetti Return
memorizzano le indicazioni di errore di trasporto nonché un valore T
(eccetto 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>
sono costruiti con Return(myTValue)
(o possono essere costruiti implicitamente da mTValue
, come nelle istruzioni return
) e gli oggetti Return<void>
sono costruiti con Void()
.
Gli oggetti Return<T>
hanno una conversione implicita da e verso il loro valore T
È possibile verificare la presenza di errori di trasporto nell'oggetto Return
chiamando il suo metodo isOk()
. Questo controllo non è richiesto; tuttavia, se si verifica un errore e non viene controllato nel momento in cui l'oggetto Return
viene distrutto o viene tentata una conversione del valore T
, il processo client verrà terminato 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 dello sviluppatore (come il passaggio nullptr
come callback sincrono), è possibile chiamare description()
sull'oggetto Return per restituire una stringa adatta per la registrazione. In questi casi, non è possibile determinare la quantità di codice eseguito sul server a seguito della chiamata non riuscita. Viene fornito anche il metodo isDeadObject()
. Questo metodo indica che !isOk()
è dovuto al fatto che l'oggetto remoto si è bloccato o non esiste più. isDeadObject()
implica sempre !isOk()
.
Ritorno per valore
Se l'istruzione generates
è mappata a una singola primitiva C++, nell'elenco dei parametri non è presente alcun parametro di callback. Un'implementazione fornisce invece il valore restituito T
in un oggetto Return<T>
, che può essere generato in modo implicito dal tipo primitivo T
. Per esempio:
Return<uint32_t> someMethod() { uint32_t return_data = ...; // Compute return_data return return_data; };
Viene fornito anche il metodo Return<*>::withDefault
. Questo metodo fornisce un valore nei casi in cui il valore restituito è !isOk()
. Questo metodo inoltre contrassegna automaticamente l'oggetto restituito come corretto in modo che il processo client non venga terminato.
Restituisce utilizzando il parametro di callback
Una richiamata può restituire il valore restituito dalla funzione HIDL al chiamante. Il prototipo del callback è un oggetto std::function
con parametri (presi dall'istruzione generates
) mappati su tipi C++. Il suo valore restituito è void: la richiamata stessa 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 di fornire il valore restituito. Poiché i valori restituiti sono già trasferiti utilizzando il callback, il parametro del modello T
è void
:
Return<void> someMethod(someMethod_cb _cb);
Dalla loro implementazione C++, le implementazioni server dovrebbero restituire Void()
, che è una funzione inline statica che restituisce un oggetto Return<void>
. Esempio di una tipica implementazione del metodo 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 restituito sarà Return<void>.
Funzioni unidirezionali
Le funzioni contrassegnate con la parola chiave oneway
sono funzioni asincrone (i client non si bloccheranno durante l'esecuzione) e non hanno valori restituiti. La firma C++ di una funzione oneway
non avrà un parametro di callback nell'elenco dei parametri e il relativo valore restituito C++ sarà Return<void>
.