Примитивные типы
В языке IDL поддерживаются следующие примитивные типы:
SInt8
, SInt16
, SInt32
, SInt64
(знаковое целое число);UInt8
, UInt16
, UInt32
, UInt64
(беззнаковое целое число);Handle
(значение, двоичное представление которого состоит из нескольких полей, включая поле дескриптора и поле маски прав дескриптора);bytes<
<размер в байтах
>>
(байтовый буфер);string<
<размер в байтах
>>
(строковый буфер).Байтовый буфер представляет собой область памяти с размером, не превышающим заданного числа байт. Строковый буфер представляет собой байтовый буфер, последний байт которого является терминирующим нулем. Максимальный размер строкового буфера на единицу больше заданного из-за наличия дополнительного байта с терминирующим нулем. Для передачи байтового или строкового буфера через IPC будет задействовано столько памяти, сколько фактически занимает этот буфер.
Для числовых типов можно объявлять именованные константы с помощью ключевого слова const
:
const UInt32 DeviceNameMax = 64;
const UInt32 HandleTypeUserLast = 0x0001FFFF;
Константы используются, чтобы избежать проблемы "магических чисел". К примеру, если в IDL-описании определены константы для кодов возврата интерфейсного метода, то при описании политики можно интерпретировать эти коды без дополнительных сведений.
Помимо примитивных типов в языке IDL поддерживаются составные типы: объединения, структуры, массивы и последовательности. В определении составных типов константы примитивных типов могут применяться как параметры (например, чтобы задать размер массива).
Конструкции bytes<
<размер в байтах
>>
и string<
<размер в байтах
>>
используются в определениях составных типов, сигнатурах интерфейсных методов и при создании псевдонимов типов, так как сами по себе они определяют анонимные типы (типы без имени).
Объединения
Объединение позволяет хранить данные разных типов в одной области памяти. В IPC-сообщении объединение снабжается дополнительным полем tag
, позволяющим определить, какой именно член объединения используется.
Для определения объединения используется следующая конструкция:
union <имя типа> {
<тип члена> <имя члена>;
...
}
Пример определения объединения:
union ExitInfo {
UInt32 code;
ExceptionInfo exc;
}
Структуры
Для определения структуры используется следующая конструкция:
struct <имя типа> {
<тип поля> <имя поля>;
...
}
Пример определения структуры:
struct SessionEvqParams {
UInt32 count;
UInt32 align;
UInt32 size;
}
Массивы
Для определения массива используется следующая конструкция:
array<<тип элементов, число элементов>>
Эта конструкция используется в определениях других составных типов, сигнатурах интерфейсных методов и при создании псевдонимов типов, так как сама по себе она определяет анонимный тип.
Последовательности
Последовательность представляет собой массив переменного размера. При определении последовательности указывается максимальное число ее элементов, однако фактически можно передать (через IPC) меньшее их число. При этом для передачи будет задействовано столько памяти, сколько занимают передаваемые элементы.
Для определения последовательности используется следующая конструкция:
sequence<<тип элементов, число элементов>>
Эта конструкция используется в определениях других составных типов, сигнатурах интерфейсных методов и при создании псевдонимов типов, так как сама по себе она определяет анонимный тип.
Типы на основе составных типов
На основе составных типов могут быть определены другие составные типы. При этом определение массива или последовательности может быть вложено в определение другого типа:
struct BazInfo {
array<UInt8, 100> a;
sequence<sequence<UInt32, 100>, 200> b;
string<100> c;
bytes<4096> d;
UInt64 e;
}
Определение объединения или структуры не может быть вложено в определение другого типа. Однако в определение типа может быть включено заранее описанное определение объединения или структуры. Это выполняется посредством указания в определении типа имен включаемых типов:
union foo {
UInt32 value1;
UInt8 value2;
}
struct bar {
UInt32 a;
UInt8 b;
}
struct BazInfo {
foo x;
bar y;
}
Создание псевдонимов типов
Псевдонимы типов используются для повышения удобства работы с типами. Псевдонимы типов могут применяться, например, для того, чтобы задать типам с абстрактными именами мнемонические имена. Также назначение псевдонимов для анонимных типов позволяет получить именованные типы.
Для создания псевдонима типа используется следующая конструкция:
typedef <имя типа/определение анонимного типа> <псевдоним типа>
Пример создания мнемонических псевдонимов:
typedef UInt64 ApplicationId;
typedef Handle PortHandle;
Пример создания псевдонима определению массива:
typedef array<UInt8, 4> IP4;
Пример создания псевдонима определению последовательности:
const UInt32 MaxDevices = 8;
struct Device {
string<32> DeviceName;
UInt8 DeviceID;
}
typedef sequence<Device, MaxDevices> Devices;
Пример создания псевдонима определению объединения:
union foo {
UInt32 value1;
UInt8 value2;
}
typedef foo bar;
Определение анонимных типов в сигнатурах интерфейсных методов
Анонимные типы могут быть определены в сигнатурах интерфейсных методов.
Пример определения последовательности в сигнатуре интерфейсного метода:
Poll(in Generation generation,
in UInt32 timeout,
out Generation currentGeneration,
out sequence<Report, DeviceMax> report,
out UInt32 count,
out UInt32 rc);
В начало