Funkcje w interfejsie HIDL są mapowane na metody w autogenerowanej deklaracji klasy C++ IFoo
. Nazwa każdej funkcji pozostaje taka sama w C++; w następnych sekcjach opisano, jak argumenty i wartości zwracane HIDL są tłumaczone na 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 wskaźnik const.
W przypadku każdej funkcji HIDL, która zwraca wartość (zawiera instrukcję generates
), lista parametrów C++ ma dodatkowy argument: funkcję wywołania zwrotnego, która jest wywoływana z wartościami zwracanymi funkcji HIDL.
Jest 1 wyjątek: jeśli klauzula generates
zawiera 1 parametr, który jest bezpośrednio mapowany na typ prymitywny C++, używana jest elidacja funkcji zwrotnej (funkcja zwrotna jest usuwana, a wartość zwracana jest zwracana z funkcji za pomocą zwykłego instrukcji return
).
Wartości zwracane przez funkcję
Podane niżej funkcje zwracają wartości.
Błędy transportu i typ zwracania
Instrukcja generates
może prowadzić do utworzenia 3 rodzajów podpisów funkcji:
- W przypadku tylko jednej wartości zwrotnej, która jest typem pierwotnym C++, wartość zwrotna
generates
jest zwracana przez wartość funkcji w obiekcieReturn<T>
. - W bardziej skomplikowanych przypadkach wartości zwracane
generates
są zwracane za pomocą parametru wywołania zwrotnego podanego w samym wywołaniu funkcji, a funkcja zwracaReturn<void>
. - Jeśli nie ma instrukcji
generates
, funkcja zwracaReturn<void>
.
Wywołania RPC mogą czasami napotykać błędy transportu, np.gdy serwer przestaje działać, gdy zasoby transportu są niewystarczające do wykonania wywołania lub gdy przekazane parametry nie umożliwiają jego wykonania (np. brakuje wymaganej funkcji wywołania zwrotnego). Obiekty Return
przechowują wskazania błędów transportu, a także wartość T
(z wyjątkiem Return<void>
).
Funkcja po stronie klienta i serwera ma ten sam podpis, więc funkcja po stronie serwera musi zwracać typ Return
, mimo że jej implementacja nie sygnalizuje błędów transportu. Obiekty Return<T>
są tworzone za pomocą funkcji Return(myTValue)
(lub mogą być tworzone domyślnie z poziomu funkcji mTValue
, np. w wyrażeniach return
), a obiekty Return<void>
są tworzone za pomocą funkcji Void()
.
Obiekty Return<T>
są domyślnie konwertowane na wartość T
i z niej. Aby sprawdzić, czy obiekt Return
zawiera błędy transportu, wywołaj metodę isOk()
. To sprawdzenie nie jest wymagane, ale jeśli wystąpi błąd i nie zostanie on sprawdzony przed zniszczeniem obiektu Return
lub próbą przekształcenia wartości T
, proces klienta zostanie przerwany, a błąd zostanie zarejestrowany. Jeśli isOk()
wskazuje na błąd transportu lub błąd wywołania spowodowany błędem logicznym w kodzie dewelopera (np. przekazanie nullptr
jako wywołania zwrotnego synchronicznego), obiekt Return może wywołać metodę description()
, aby zwrócić ciąg znaków odpowiedni do rejestrowania. W takich przypadkach nie można określić, ile kodu zostało wykonane na serwerze w wyniku nieudanego wywołania. Dostępna jest też metoda isDeadObject()
. Ta metoda wskazuje, że !isOk()
występuje, ponieważ obiekt zdalny uległ awarii lub już nie istnieje. isDeadObject()
zawsze zakłada !isOk()
.
Zwracanie wartości
Jeśli instrukcja generates
odwołuje się do pojedynczego typu podstawowego C++, na liście parametrów nie ma parametru callback. Zamiast tego implementacja udostępnia wartość zwracaną T
w obiekcie Return<T>
, który może być domyślnie generowany z podstawowego typu T
. Przykład:
Return<uint32_t> someMethod() { uint32_t return_data = ...; // Compute return_data return return_data; };
Dostępna jest też metoda Return<*>::withDefault
. Ta metoda dostarcza wartość w przypadkach, gdy zwracana wartość to !isOk()
.
Ta metoda automatycznie oznacza zwracany obiekt jako „OK”, dzięki czemu proces klienta nie zostanie przerwany.
Zwracanie wartości za pomocą parametru wywołania zwrotnego
Funkcja wywołania zwrotnego może przekazać zwracaną wartość funkcji HIDL do wywołującego.
Prototyp funkcji wywołania zwrotnego to obiekt std::function
z parametrami (pochodzącymi z instrukcji generates
) mapowanymi na typy C++. Jego wartość zwracana jest pusta – samo wywołanie zwrotne nie zwraca wartości.
Zwracana wartość funkcji C++ z parametrem wywołania zwrotnego ma typ Return<void>
. Implementacja serwera odpowiada tylko za podanie wartości zwracanej. Ponieważ wartości zwracane są już przeniesione za pomocą funkcji wywołania zwrotnego, parametr szablonu T
ma wartość void
:
Return<void> someMethod(someMethod_cb _cb);
Implementacje na serwerze powinny zwracać Void()
, która jest stałą wbudowaną funkcją zwracającą obiekt Return<void>
. Przykład typowej implementacji metody serwera 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
Podpis funkcji w C++, który nie zawiera instrukcji generates
, nie będzie zawierać parametru funkcji zwrotnej na liście parametrów. Typ zwrotu to Return<void>.
Funkcje jednokierunkowe
Funkcje oznaczone słowem kluczowym oneway
są asynchroniczne (ich wykonanie nie blokuje klientów) i nie zwracają wartości. Podpis funkcji oneway
w C++ nie będzie zawierać parametru callback na liście parametrów, a jego zwracana wartość w C++ będzie miała postać Return<void>
.