Объявления данных HIDL генерируют структуры данных стандартной компоновки C++. Эти структуры могут быть размещены в любом удобном для вас месте (в стеке, в файловой или глобальной области видимости или в куче) и могут быть составлены таким же образом. Клиентский код вызывает прокси-код HIDL, передавая ссылки на константы и примитивные типы, в то время как заглушка и прокси-код скрывают детали сериализации.
Примечание. Код, написанный разработчиком, не требуется для явной сериализации или десериализации структур данных.
В таблице ниже примитивы HIDL сопоставляются с типами данных C++:
| Тип HIDL | Тип С++ | Заголовок/Библиотека | 
|---|---|---|
enum  | enum class  | |
uint8_t..uint64_t  | uint8_t..uint64_t  | <stdint.h>  | 
int8_t..int64_t  | int8_t..int64_t  | <stdint.h>  | 
float  | float  | |
double  | double  | |
vec<T>  | hidl_vec<T>  | libhidlbase  | 
T[S1][S2]...[SN]  | T[S1][S2]...[SN]  | |
string  | hidl_string  | libhidlbase  | 
handle  | hidl_handle  | libhidlbase  | 
safe_union  | (custom) struct  | |
struct  | struct  | |
union  | union  | |
fmq_sync  | MQDescriptorSync  | libhidlbase  | 
fmq_unsync  | MQDescriptorUnsync  | libhidlbase  | 
Разделы ниже описывают типы данных более подробно.
перечисление
Перечисление в HIDL становится перечислением в C++. Например:
enum Mode : uint8_t { WRITE = 1 << 0, READ = 1 << 1 };
enum SpecialMode : Mode { NONE = 0, COMPARE = 1 << 2 };
… становится:
enum class Mode : uint8_t { WRITE = 1, READ = 2 };
enum class SpecialMode : uint8_t { WRITE = 1, READ = 2, NONE = 0, COMPARE = 4 };
 Начиная с Android 10, перечисление можно повторять с помощью ::android::hardware::hidl_enum_range . Этот диапазон включает все перечислители в том порядке, в котором они появляются в исходном коде HIDL, начиная с родительского перечисления и заканчивая последним дочерним. Например, этот код перебирает WRITE , READ , NONE и COMPARE именно в таком порядке. Учитывая SpecialMode выше:
template <typename T>
using hidl_enum_range = ::android::hardware::hidl_enum_range<T>
for (SpecialMode mode : hidl_enum_range<SpecialMode>) {...}
 hidl_enum_range также реализует обратные итераторы и может использоваться в контексте constexpr . Если значение появляется в перечислении несколько раз, значение появляется в диапазоне несколько раз.
битовое поле<T>
 bitfield<T> (где T — определяемое пользователем перечисление) становится базовым типом этого перечисления в C++. В приведенном выше примере bitfield<Mode> становится uint8_t .
век<Т>
 Шаблон класса hidl_vec<T> является частью libhidlbase и может использоваться для передачи вектора любого типа HIDL произвольного размера. Сопоставимый контейнер фиксированного размера — hidl_array . hidl_vec<T> также можно инициализировать, чтобы он указывал на внешний буфер данных типа T , используя hidl_vec::setToExternal() .
 Помимо создания/вставки структуры в сгенерированный заголовок C++, использование vec<T> создает некоторые удобные функции для преобразования в/из std::vector и голых указателей T Если vec<T> используется в качестве параметра, функция, использующая его, будет перегружена (будут сгенерированы два прототипа), чтобы принять и передать как структуру HIDL, так и тип std::vector<T> для этого параметра.
множество
 Массивы констант в hidl представлены классом hidl_array в libhidlbase . hidl_array<T, S1, S2, …, SN> представляет N-мерный массив фиксированного размера T[S1][S2]…[SN] .
нить
 Класс hidl_string (часть libhidlbase ) может использоваться для передачи строк через интерфейсы HIDL и определен в /system/libhidl/base/include/hidl/HidlSupport.h . Первое место хранения в классе — это указатель на его символьный буфер.
 hidl_string умеет преобразовывать в и из std::string and char* (строка в стиле C) с помощью operator= , неявных приведений и .c_str() . Строковые структуры HIDL имеют соответствующие конструкторы копирования и операторы присваивания для:
-  Загрузите строку HIDL из 
std::stringили строки C. -  Создайте новый 
std::stringиз строки HIDL. 
 Кроме того, строки HIDL имеют конструкторы преобразования, поэтому строки C ( char * ) и строки C++ ( std::string ) могут использоваться в методах, которые принимают строку HIDL.
структура
 Структура в struct может содержать только типы данных фиксированного размера и не содержать функций. Определения структур HIDL сопоставляются непосредственно со struct стандартной компоновки в C++, гарантируя, что struct имеют согласованную компоновку памяти. Структура может включать типы HIDL, включая handle , string и vec<T> , которые указывают на отдельные буферы переменной длины.
ручка
ПРЕДУПРЕЖДЕНИЕ. Адреса любого типа (даже адреса физических устройств) никогда не должны быть частью собственного дескриптора. Передача этой информации между процессами опасна и делает их уязвимыми для атак. Любые значения, передаваемые между процессами, должны быть проверены перед использованием для поиска выделенной памяти внутри процесса. В противном случае плохие дескрипторы могут привести к неправильному доступу к памяти или повреждению памяти.
 Тип handle представлен структурой hidl_handle в C++, которая представляет собой простую оболочку вокруг указателя на константный объект const native_handle_t (это уже давно присутствует в Android).
typedef struct native_handle
{
    int version;        /* sizeof(native_handle_t) */
    int numFds;         /* number of file descriptors at &data[0] */
    int numInts;        /* number of ints at &data[numFds] */
    int data[0];        /* numFds + numInts ints */
} native_handle_t;
 По умолчанию hidl_handle не становится владельцем указателя native_handle_t , который он обертывает. Он просто существует для безопасного хранения указателя на native_handle_t , чтобы его можно было использовать как в 32-, так и в 64-битных процессах.
 Сценарии, в которых hidl_handle владеет дескрипторами вложенных файлов, включают:
-  После вызова 
setTo(native_handle_t* handle, bool shouldOwn)с параметромshouldOwn, установленным в значениеtrue -  Когда объект 
hidl_handleсоздается путем копирования конструкции из другого объектаhidl_handle -  Когда объект 
hidl_handleкопируется из другого объектаhidl_handle 
 hidl_handle обеспечивает как неявные, так и явные преобразования в/из объектов native_handle_t* . Основное использование типа handle в HIDL — передача файловых дескрипторов через интерфейсы HIDL. Таким образом, один файловый дескриптор представлен native_handle_t без int и одним fd . Если клиент и сервер находятся в разных процессах, реализация RPC автоматически позаботится об дескрипторе файла, чтобы оба процесса могли работать с одним и тем же файлом.
 Хотя дескриптор файла, полученный процессом в hidl_handle , будет действительным в этом процессе, он не будет сохраняться за пределами принимающей функции (он будет закрыт после возврата из функции). Процесс, который хочет сохранить постоянный доступ к файловому дескриптору, должен выполнить dup() вложенные файловые дескрипторы или скопировать весь объект hidl_handle .
объем памяти
 Тип memory HIDL сопоставляется с классом hidl_memory в libhidlbase , который представляет собой несопоставленную общую память. Это объект, который должен передаваться между процессами для совместного использования памяти в HIDL. Чтобы использовать общую память:
-  Получите экземпляр 
IAllocator(в настоящее время доступен только экземпляр «ashmem») и используйте его для выделения общей памяти. -  
IAllocator::allocate()возвращает объектhidl_memory, который можно передать через HIDL RPC и отобразить в процесс с помощью функцииlibhidlmemorymapMemory. -  
mapMemoryвозвращает ссылку на объектsp<IMemory>, который можно использовать для доступа к памяти. (IMemoryиIAllocatorопределены вandroid.hidl.memory@1.0.) 
 Экземпляр IAllocator можно использовать для выделения памяти:
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
using ::android::hidl::allocator::V1_0::IAllocator;
using ::android::hidl::memory::V1_0::IMemory;
using ::android::hardware::hidl_memory;
....
  sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
  ashmemAllocator->allocate(2048, [&](bool success, const hidl_memory& mem) {
        if (!success) { /* error */ }
        // now you can use the hidl_memory object 'mem' or pass it around
  }));
 Фактические изменения в памяти должны выполняться через объект IMemory либо на стороне, создавшей mem , либо на стороне, которая получает ее через HIDL RPC.
// Same includes as above sp<IMemory> memory = mapMemory(mem); void* data = memory->getPointer(); memory->update(); // update memory however you wish after calling update and before calling commit data[0] = 42; memory->commit(); // … memory->update(); // the same memory can be updated multiple times // … memory->commit();
интерфейс
 Интерфейсы могут передаваться как объекты. Слово interface можно использовать как синтаксический сахар для типа android.hidl.base@1.0::IBase ; кроме того, текущий интерфейс и любые импортированные интерфейсы будут определены как тип.
 Переменные, содержащие интерфейсы, должны быть надежными указателями: sp<IName> . Функции HIDL, которые принимают параметры интерфейса, будут преобразовывать необработанные указатели в надежные указатели, вызывая неинтуитивное поведение (указатель может быть очищен неожиданно). Во избежание проблем всегда сохраняйте интерфейсы HIDL как sp<> .