Funkcje

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 obiekcie Return<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 zwraca Return<void>.
  • Jeśli nie ma instrukcji generates, funkcja zwraca Return<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>.