]>Что такое GUID и зачем он нужен

Что такое GUID и зачем он нужен

Аватар пользователя mabu

Как‐то в один прекрасный день корпорация Open Software Foundation придумала концепцию UUID — Universally Unique Identifier, вселенски уникального идентификатора. Она взяла 128‐битное число и написала для его вычисления специальный алгоритм, более‐менее равномерно выдающий значения из такого огромного диапазона. Из‐за того, что само число очень большое, вероятность выдачи алгоритмом двух одинаковых чисел невелика. На практике можно говорить, что любое новое число UUID будет уникально.

Корпорация Microsoft взяла на вооружение эту мысль и число UUID без изменения, только назвала его немного по‐другому: GUID, то есть Globally Unique Identifier, глобально уникальный идентификатор.

Microsoft применяет GUID в следующих случаях:

Ты тоже можешь использовать GUID в своих целях, например, так:

  1. Определение GUID
    1. Структура GUID
    2. IID и CLSID
    3. REFGUID, REFIID и REFCLSID
  2. Объявление GUID
    1. В тексте
    2. В коде
  3. Фуннкции для работы с GUID
    1. CoCreateGUID
    2. IsEqualGUID, IsEqualIID, IsEqualCLSID и InlineIsEqualGUID
    3. IIDFromString и CLSIDFromString
    4. StringFromGUID2
    5. StringFromIID и StringFromCLSID
  4. Примеры
    1. Генератор GUID

Определение GUID

В GUID нет чего‐то таинственного и сверхъестественного, это просто целое 128‐битное число.

Так как типа данных под 128‐битного целого нет, то программисты из Microsoft нашли элегантное решение записать такое число в виде стуктуры.

Структура GUID

В заголовочном файле guiddef.bi (входит в ole2.bi) GUID объявляется в виде структуры:

Код FreeBASIC
Type _GUID
&t;Data1 As ULong
&t;Data2 As UShort
&t;Data3 As UShort
&t;Data4(0 To 7) As UByte
End Type

Type GUID As _GUID

IID и CLSID

IID (идентификатор интерфейса) и CLSID (идентификатор класса) — это псевдонимы GUID:

Код FreeBASIC
Type IID As GUID

Type CLSID As GUID

REFGUID, REFIID и REFCLSID

Поскольку размер GUID — 16 байтов, мы будем передавать его в функции не по значению, а по ссылке. Программистам из Microsoft показалось утомительным писать каждый раз что‐то вроде ByVal As Const IID Const Ptr, поэтому они определили в заголовочнике типы данных для указателей (Reference — отсюда приставка REF) на GUID, IID и CLSID:

Код FreeBASIC
Type REFGUID As Const GUID Const Ptr

Type REFIID As Const IID Const Ptr

Type REFCLSID As Const IID Const Ptr

Теперь можно объявлять параметр функции так: ByVal As REFIID.

Объявление GUID

В тексте

В тексте GUID записывается в виде строки из тридцати двух шестнадцатеричных цифр, разбитой на группы дефисоминусами и опционально окружённой фигурными скобками. Ты уже наверняка где‐нибудь встречал похожие записи GUID:

Код Простой текст
{90125688-9C3F-4E6F-8D96-A8C71B8251E0}

{6F9619FF-8B86-D011-B42D-00CF4FC964FF}

{717473E7-54B3-4580-A086-2199430834DA}

{4C9E6590-A9C5-40AD-9E13-AB55F6AAC05F}

В коде

В исходном коде объявлять переменную типа GUID можно через длинный ряд шестнадцатеричных чисел. Посмотрим как объявляется IID интерфейса IXmlHttpRequest и CLSID класса XmlHttpRequest, который его реализует:

Код FreeBASIC
Dim IID_IXmlHttpRequest As IID = Type(&hED8C108D, &h4349, &h11D2, _
&t;{&h91, &hA4, &h00, &hC0, &h4F, &h79, &h69, &hE8})

Dim CLSID_XMLHTTPREQUEST As CLSID = Type(&hED8C108E, &h4349, &h11D2, _
&t;{&h91, &hA4, &h00, &hC0, &h4F, &h79, &h69, &hE8})

Фуннкции для работы с GUID

CoCreateGUID

Функция CoCreateGuid принимает указатель структуру GUID и заполняет её данными.

Код FreeBASIC
Declare Function CoCreateGuid( _
&t;ByVal pguid As GUID Ptr _
)As HRESULT

Параметры

pguid
Указатель на переменную, куда будет записан созданный GUID.

Возвращаемое значение

В случае успеха функция возвращает константу S_OK, в случае ошибки — что‐то другое.

Однако так как тип возвращаемого значения HRESULT, то проверять успешность выполненения функции следует макросами SUCCEEDED и FAILED, а не сравнивать результат напрямую с константой.

IsEqualGUID, IsEqualIID, IsEqualCLSID и InlineIsEqualGUID

Эти макросы предназначены для сравнения двух GUID, IID или CLSID.

Код FreeBASIC
Declare Function IsEqualGUID( _
&t;ByVal rguid1 As REFGUID, _
&t;ByVal rguid2 As REFGUID _
)As Boolean

Declare Function IsEqualIID( _
&t;ByVal rguid1 As REFIID, _
&t;ByVal rguid2 As REFIID _
)As Boolean

Declare Function IsEqualCLSID( _
&t;ByVal rguid1 As REFCLSID, _
&t;ByVal rguid2 As REFCLSID _
)As Boolean

Declare Function InlineIsEqualGUID( _
&t;ByVal rguid1 As REFGUID, _
&t;ByVal rguid2 As REFGUID _
)As Boolean

Макросы IsEqualGUID, IsEqualIID и IsEqualCLSID сравнивают, вызывая функцию memcmp, а InlineIsEqualGUID делает это в коде, сравнивая структуру побайтово.

IIDFromString и CLSIDFromString

Преобразуют строку в IID или CLSID.

Код FreeBASIC
Declare Function IIDFromString( _
&t;ByVal lpsz As LPCOLESTR, _
&t;ByVal lpiid As LPIID _
)As HRESULT

Declare Function CLSIDFromString( _
&t;ByVal lpsz As LPCOLESTR, _
&t;ByVal pclsid As LPCLSID _
)As HRESULT

Параметры

pguid
указатель на строку с IID или CLSID.
lpiid или pclsid
Указатель на переменную, куда будет записан GUID.

Возвращаемое значение

В случае успеха функции возвращают константу S_OK, в случае ошибки — что‐то другое.

Однако так как тип возвращаемого значения HRESULT, то проверять успешность выполненения функции следует макросами SUCCEEDED и FAILED, а не сравнивать результат напрямую с константой.

StringFromGUID2

Преобразуют GUID в строку.

Код FreeBASIC
Declare Function StringFromGUID2( _
&t;ByVal rguid As REFGUID , _
&t;ByVal lpsz As LPOLESTR, _
&t;ByVal cchMax As Long _
)As Long

Параметры

rguid
Указатель на GUID.
lpsz
Указатель на буфер, куда будет записана строка.
cchMax
Длина буфера.

Возвращаемое значение

В случае успеха функция возвратит количество записанных символов, включая нулевой.

В случае ошибки, когда буфер под строку слишком мал, вернёт 0.

StringFromIID и StringFromCLSID

Преобразуют IID или CLSID в строку.

Код FreeBASIC
Declare Function StringFromIID( _
&t;ByVal rclsid As REFIID , _
&t;ByVal lplpsz As LPOLESTR Ptr _
)As HRESULT

Declare Function StringFromCLSID( _
&t;ByVal rclsid As REFCLSID, _
&t;ByVal lplpsz As LPOLESTR Ptr _
)As HRESULT

Параметры

rclsid
Указатель на IID или CLSID.
lplpsz
Указатель на указатель, по которому будет записан адрес полученной строки. После использования выделенную память следует освободить функцией CoTaskMemFree.

Возвращаемое значение

В случае успеха функция возвратит константу S_OK.

В случае ошибки, когда недостаточно памяти, вернёт E_OUTOFMEMORY.

Однако так как тип возвращаемого значения HRESULT, то проверять успешность выполненения функции следует макросами SUCCEEDED и FAILED, а не сравнивать результат напрямую с константой.

Примеры

Генератор GUID

В этом простом примере посмотрим как создать GUID и вывести его на консоль.

Код FreeBASIC
#ifndef unicode
#define unicode
#endif
#include "windows.bi"
#include "win\ole2.bi"

' Наш IID интерфейса
Dim IID_IFace As IID = Any
CoCreateGUID(@IID_IFace)

' Получаем строку
Dim pstrIID_IFace As WString Ptr = Any
StringFromIID(@IID_IFace, @pstrIID_IFace)

' Выводим на консоль
Print *pstrIID_IFace

' Очищаем память
CoTaskMemFree(pstrIID_IFace)

Не забудь сохранить исходник в юникодной кодировке: UTF-8 или UTF-16.

Поделись ссылочкой в социальных сетях