Существует две причины, по которым идентификаторы GUID так широко используются в COM:
1. GUID это всего лишь число. Любой язык программирования может оперировать им.
2. Каждый GUID, создаваемый на любой машине, уникален (если создан правильно). Следовательно, два COM-разработчика не могут использовать одни и те же GUID. Это решает проблему по выделению уникальных GUID и устраняет необходимость в специальном центре по выделению GUID (как, например, при регистрации доменов в Internet).
Наконец,
Каждый язык реализует операции с объектами по-разному. Например, в C++ вы создаете объекты на стеке, либо с помощью new динамически выделяете для них место в "куче". Поскольку COM должна быть нейтральна к языку, библиотека COM включает свои собственные средства управления объектами. Сравним управление объектами в COM и C++:
• В C++ используется оператор new, либо объект создается на стеке.
• В COM вызывается специальная API-функция библиотеки COM.
• В C++ используется оператор delete, либо объект удаляется автоматически при выходе из области видимости.
• В COM каждый объект хранит свой собственный счетчик обращений. Когда вы заканчиваете работу с объектом, вы должны сообщить ему, что он вам больше не нужен. Когда счетчик обращений равен 0, объект сам выгружается из памяти.
Теперь, между этими двумя стадиями – создания и удаления объекта – вы, естественно, должны
Для создания COM-объекта и получения интерфейса из этого объекта (напомню, что COM-объект может содержать несколько интерфейсов) вы должны вызвать библиотечную функцию CoCreateInstance. Прототип CoCreateInstance:
HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv);
Описание параметров:
rclsid | CLSID CO-класса. Например, вы можете передать CLSID_ShellLink при создании COM-объекта, который используется для создания ярлыков. |
pUnkOuter | Этот параметр используется только при агрегации COM-объектов, когда берется существующий CO-класс и в него добавляются новые методы. Для наших целей мы должны передать NULL для указания на то, что агрегация использоваться не будет. |
dwClsContext | Указывает на тип COM-сервера. В этой статье будет использоваться простейший тип сервера – in-process DLL, поэтому в качестве параметра будет передаваться константа CLSCTX_INPROC_SERVER. Предостережение: не используйте CLSCTX_ALL (она установлена в ATL по умолчанию), т.к. это может привести к ошибке в системах Windows 95, где не инсталлирован DCOM. |
riid | Это IID интерфейса, который вы хотите получить. Например, вы должны передать IID_IShellLink для получения указателя на интерфейс IShellLink. |
ppv | Адрес указателя на интерфейс. Библиотека COM возвращает указатель на запрашиваемый интерфейс через этот параметр. |