Funkcje w interfejsie HIDL są mapowane na metody w automatycznie generowanej deklaracji klasy IFoo
C++. Nazwa każdej funkcji pozostaje taka sama w C++; w poniższych sekcjach opisano, w jaki sposób argumenty HIDL i zwracane wartości są tłumaczone na język C++.
Parametry funkcji
Argumenty wymienione w pliku .hal
są mapowane na typy danych C++. Argumenty, które nie są mapowane na prymitywny typ C++, są przekazywane przez odwołanie do stałej.
Dla każdej funkcji HIDL, która ma wartość zwracaną (posiada instrukcję generates
), lista parametrów C++ dla tej funkcji zawiera dodatkowy argument: funkcję wywołania zwrotnego, która jest wywoływana z wartościami zwracanymi przez funkcję HIDL. Jest jeden wyjątek : jeśli klauzula generates
zawiera pojedynczy parametr, który bezpośrednio odwzorowuje element podstawowy C++, stosowana jest eliminacja wywołania zwrotnego (wywołanie zwrotne jest usuwane, a wartość zwracana jest zwracana z funkcji za pomocą zwykłej instrukcji return
).
Funkcja zwraca wartości
Poniższe funkcje mają wartości zwracane.
Błędy transportowe i rodzaj zwrotu
Instrukcja generates
może skutkować trzema typami sygnatur funkcji:
- Tylko w przypadku jednej wartości zwracanej, która jest prymitywem języka C++,
generates
wartość zwracana jest zwracana przez wartość z funkcji w obiekcieReturn<T>
. - W bardziej skomplikowanych przypadkach
generates
wartości zwracane są zwracane przez parametr wywołania zwrotnego dostarczony z samym wywołaniem funkcji, a funkcja zwracaReturn<void>
. - Jeśli nie istnieje żadna instrukcja
generates
, funkcja zwracaReturn<void>
.
Wywołania RPC mogą czasami napotykać błędy transportu, np. gdy serwer umiera, gdy zasoby transportowe są niewystarczające do zakończenia połączenia lub gdy przekazane parametry nie pozwalają na dokończenie wywołania (tak jak brak wymaganej funkcji wywołania zwrotnego). Obiekty Return
przechowują wskazania błędów transportu oraz wartość T
(z wyjątkiem Return<void>
).
Ponieważ funkcje po stronie klienta i serwera mają tę samą sygnaturę, funkcja po stronie serwera musi zwrócić typ Return
, nawet jeśli jej implementacja nie sygnalizuje błędów transportu. Obiekty Return<T>
są konstruowane za pomocą Return(myTValue)
(lub mogą być konstruowane niejawnie na podstawie mTValue
, na przykład w instrukcjach return
), a obiekty Return<void>
są konstruowane za pomocą Void()
.
Obiekty Return<T>
mają niejawną konwersję do i z wartości T
Obiekt Return
można sprawdzić pod kątem błędów transportu, wywołując jego metodę isOk()
. Kontrola ta nie jest wymagana; jeśli jednak wystąpi błąd i nie zostanie on sprawdzony do czasu zniszczenia obiektu Return
lub próby konwersji wartości T
, proces klienta zostanie zabity i zarejestrowany zostanie błąd. Jeśli isOk()
wskazuje błąd transportu lub niepowodzenie wywołania z powodu błędu logicznego w kodzie programisty (takiego jak przekazanie nullptr
jako synchronicznego wywołania zwrotnego), wówczas na obiekcie Return można wywołać description()
w celu zwrócenia ciągu znaków odpowiedniego do rejestrowania. W takich przypadkach nie można określić, ile kodu mogło zostać wykonane na serwerze w wyniku nieudanego wywołania. Dostępna jest także metoda isDeadObject()
. Ta metoda wskazuje, że !isOk()
wynika z awarii obiektu zdalnego lub już nie istnieje. isDeadObject()
zawsze oznacza !isOk()
.
Zwróć według wartości
Jeśli instrukcja generates
jest mapowana na pojedynczy element podstawowy języka C++, na liście parametrów nie ma żadnego parametru wywołania zwrotnego. Zamiast tego implementacja zapewnia wartość zwracaną T
w obiekcie Return<T>
, który można niejawnie wygenerować na podstawie typu pierwotnego T
. Na przykład:
Return<uint32_t> someMethod() { uint32_t return_data = ...; // Compute return_data return return_data; };
Dostępna jest także metoda Return<*>::withDefault
. Ta metoda dostarcza wartość w przypadkach, gdy wartością zwracaną jest !isOk()
. Ta metoda automatycznie oznacza również obiekt zwracany jako prawidłowy, dzięki czemu proces klienta nie zostanie zabity.
Wróć za pomocą parametru wywołania zwrotnego
Wywołanie zwrotne może przekazać wartość zwracaną przez funkcję HIDL z powrotem do osoby wywołującej. Prototypem wywołania zwrotnego jest obiekt std::function
z parametrami (pobranymi z instrukcji generates
) odwzorowanymi na typy C++. Zwracana przez nią wartość jest nieważna — samo wywołanie zwrotne nie zwraca wartości.
Wartość zwracana przez funkcję C++ z parametrem wywołania zwrotnego ma typ Return<void>
. Implementacja serwera odpowiada jedynie za dostarczenie wartości zwracanej. Ponieważ wartości zwracane są już przesyłane za pomocą wywołania zwrotnego, parametr szablonu T
jest void
:
Return<void> someMethod(someMethod_cb _cb);
Z implementacji w C++ implementacje serwerowe powinny zwracać Void()
, która jest statyczną funkcją wstawianą zwracającą obiekt Return<void>
. Przykład typowej implementacji metody serwerowej z parametrem wywołania zwrotnego:
Return<void> someMethod(someMethod_cb _cb) { // Do some processing, then call callback with return data hidl_vec<uint32_t> vec = ... _cb(vec); return Void(); };
Funkcje bez wartości zwracanych
Sygnatura C++ funkcji bez instrukcji generates
nie będzie miała parametru wywołania zwrotnego na liście parametrów. Typ zwracany będzie Return<void>.
Funkcje jednokierunkowe
Funkcje oznaczone słowem kluczowym oneway
są funkcjami asynchronicznymi (klienci nie będą blokować ich wykonania) i nie mają zwracanych wartości. Podpis C++ funkcji oneway
nie będzie miał parametru wywołania zwrotnego na liście parametrów, a jego wartość zwracana w C++ będzie Return<void>
.