Функции в интерфейсе HIDL сопоставляются с методами в автоматически созданном объявлении класса IFoo
C++. Имя каждой функции в C++ остается прежним; в следующих разделах описывается, как аргументы и возвращаемые значения HIDL преобразуются в C++.
Параметры функции
Аргументы, перечисленные в файле .hal
, соответствуют типам данных C++. Аргументы, которые не соответствуют примитивному типу C++, передаются по константной ссылке.
Для каждой функции HIDL, которая имеет возвращаемое значение (имеет оператор generates
), список параметров C++ для этой функции имеет дополнительный аргумент: функцию обратного вызова, которая вызывается с возвращаемыми значениями функции HIDL. Есть одно исключение : если предложение generates
один параметр, который напрямую отображается в примитив C++, используется исключение обратного вызова (обратный вызов удаляется, и возвращаемое значение возвращается из функции посредством обычного оператора return
).
Возвращаемые значения функции
Следующие функции имеют возвращаемые значения.
Ошибки транспорта и тип возвращаемого значения
Оператор generates
три типа сигнатур функций:
- Только для одного возвращаемого значения, которое является примитивом C++, возвращаемое значение
generates
по значению из функции в объектеReturn<T>
. - В более сложных случаях возвращаемые значения
generates
через параметр обратного вызова, предоставляемый самим вызовом функции, и функция возвращаетReturn<void>
. - Если оператор
generates
не существует, функция возвращаетReturn<void>
.
Вызовы RPC могут иногда сталкиваться с ошибками транспорта, например, когда сервер умирает, когда транспортных ресурсов недостаточно для завершения вызова или когда переданные параметры не позволяют завершить вызов (например, отсутствие необходимой функции обратного вызова). Return
объекты хранят индикаторы ошибок транспорта, а также значение T
(кроме Return<void>
).
Поскольку функции на стороне клиента и на стороне сервера имеют одинаковую сигнатуру, функция на стороне сервера должна возвращать тип Return
, даже если ее реализация не сигнализирует об ошибках транспорта. Объекты Return<T>
создаются с помощью Return(myTValue)
(или могут быть неявно созданы из mTValue
, например, в операторах return
), а объекты Return<void>
создаются с помощью Void()
.
Объекты Return<T>
имеют неявное преобразование в свое значение T
и обратно. Объект Return
можно проверить на наличие ошибок транспорта, вызвав его метод isOk()
. Эта проверка не требуется; однако, если возникает ошибка и она не проверяется к моменту уничтожения объекта Return
или попытки преобразования значения T
, клиентский процесс будет завершен и зарегистрирована ошибка. Если isOk()
указывает на ошибку транспорта или сбой вызова из-за логической ошибки в коде разработчика (например, передача nullptr
в качестве синхронного обратного вызова), то для объекта Return можно вызвать description()
, чтобы вернуть строку, пригодную для регистрации. В таких случаях невозможно определить, какой объем кода мог быть выполнен на сервере в результате неудачного вызова. Также предусмотрен метод isDeadObject()
. Этот метод указывает, что !isOk()
вызван тем, что удаленный объект вышел из строя или больше не существует. isDeadObject()
всегда подразумевает !isOk()
.
Возврат по значению
Если оператор generates
сопоставляется с одним примитивом C++, в списке параметров нет параметра обратного вызова. Вместо этого реализация предоставляет возвращаемое значение T
в объекте Return<T>
, который может быть неявно сгенерирован из примитивного типа T
. Например:
Return<uint32_t> someMethod() { uint32_t return_data = ...; // Compute return_data return return_data; };
Также предоставляется метод Return<*>::withDefault
. Этот метод предоставляет значение в тех случаях, когда возвращаемое значение равно !isOk()
. Этот метод также автоматически помечает возвращаемый объект как нормальный, поэтому клиентский процесс не будет завершен.
Возврат с использованием параметра обратного вызова
Обратный вызов может передать возвращаемое значение функции HIDL обратно вызывающей стороне. Прототипом обратного вызова является std::function
с параметрами (взятыми из оператора generates
), сопоставленными с типами C++. Его возвращаемое значение — void — сам обратный вызов не возвращает значения.
Возвращаемое значение функции C++ с параметром обратного вызова имеет тип Return<void>
. Реализация сервера отвечает только за предоставление возвращаемого значения. Поскольку возвращаемые значения уже передаются с помощью обратного вызова, параметр шаблона T
имеет значение void
:
Return<void> someMethod(someMethod_cb _cb);
В своей реализации на C++ серверные реализации должны возвращать Void()
, которая представляет собой статическую встроенную функцию, возвращающую объект Return<void>
. Пример типичной реализации серверного метода с параметром обратного вызова:
Return<void> someMethod(someMethod_cb _cb) { // Do some processing, then call callback with return data hidl_vec<uint32_t> vec = ... _cb(vec); return Void(); };
Функции без возвращаемых значений
Сигнатура C++ функции без оператора generates
не будет иметь параметра обратного вызова в списке параметров. Тип возвращаемого значения будет Return<void>.
Односторонние функции
Функции, отмеченные ключевым словом oneway
, являются асинхронными функциями (клиенты не блокируют их выполнение) и не имеют возвращаемых значений. Сигнатура C++ oneway
функции не будет иметь параметра обратного вызова в списке параметров, а ее возвращаемое значение C++ будет Return<void>
.