Функции

Функции в интерфейсе 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 в качестве синхронного обратного вызова), то description() можно вызвать для объекта Return, чтобы вернуть строку, подходящую для ведения журнала. В таких случаях невозможно определить, какой объем кода мог быть выполнен на сервере в результате неудачного вызова. Также предоставляется метод 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> .