Функции

Функции в интерфейсе 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> .