Интерфейс является особым типом данных: он может быть реализован в одной программе, а использоваться из другой. Для этого нужно обеспечить идентификацию интерфейса при межпрограммном взаимодействии. Понятно, что программный идентификатор интерфейса для этого не подходит — разные программы пишутся разными людьми, а разные люди подчас дают одинаковые имена своим творениям. Поэтому каждому интерфейсу выдается своеобразный «паспорт» — глобально-уникальный идентификатор (Globally Unique Identifier — GUID).
Глобально-уникальный идентификатор — это 16-ти байтовое число, представленное в виде заключенной в фигурные скобки последовательности шестнадцатеричных цифр:
{DC601962-28E5-4BF7-9583-0CE22B605045} |
В среде Delphi глобально-уникальный идентификатор описывается типом данных TGUID:
type PGUID = ^TGUID; TGUID = packed record D1: Longword; D2: Word; D3: Word; D4: array[0..7] of Byte; end; |
Константы с типом TGUID разрешено инициализировать строковым представлением глобально-уникального идентификатора. Компилятор сам преобразует строку в запись с типом TGUID. Пример:
const InterfaceID: TGUID = '{DC601962-28E5-4BF7-9583-0CE22B605045}'; |
Если глобально-уникальный идентификатор назначается интерфейсу, то он записывается после ключевого слова interface и заключается в квадратные скобки, например:
type IInterface = interface ['{00000000-0000-0000-C000-000000000046}'] ... end; |
В будущем нашему интерфейсу ITextReader понадобится глобально-уникальный идентификатор. Но как его выбрать так, чтобы он оказался уникальным? Очень просто — нажмите в редакторе кода комбинацию клавиш Ctrl+Shift+G.
type ITextReader = interface ['{DC601962-28E5-4BF7-9583-0CE22B605045}'] // Результат нажатия Ctrl+Shift+G ... end; |
Генерация глобально-уникальных идентификаторов осуществляется системой Windows по специальному алгоритму, в котором задействуется адрес сетевого адаптера, текущее время и генератор случайных чисел. Можете смело полагаться на уникальность всех получаемых идентификаторов.
Наличие глобально-уникального идентификатора в описании интерфейса не является обязательным, однако использование интерфейса без такого идентификатора ограничено, например, запрещено использовать оператор as для преобразования одних интерфейсов в другие.
Если у интерфейса есть глобально-уникальный идентификатор, то программный идентификатор интерфейса можно использовать там, где ожидается тип данных TGUID, например:
const IID_ITextReader: TGUID = '{DC601962-28E5-4BF7-9583-0CE22B605045}'; function TestInterface(const IID: TGUID): Boolean; begin ... TestInterface(ITextReader); // эквивалентно TestInterface(IID_ITextReader); ...end; |