Сущность технологии СОМ. Библиотека программиста | страница 107



0, IID_IOleItemContainer, (void**)&poic);

if (SUCCEEDED(hr)) {

hr = poic->GetObject(OLESTR(«Ursus»), BINDSPEED_INFINITE,

0, IID_IApe, (void**)&rpApe);

poic->Release();

}

return hr; }


Отметим, что уровень изоляции (indirection), обеспеченный использованием CoGetObject, позволяет клиенту менять стратегию связывания просто путем чтения различных отображаемых имен из файла конфигурации или из ключа реестра.


Моникеры и сохраняемость

Обсуждение моникеров не может быть полным без обсуждения файлового моникера (File Moniker). Напомним, что СОМ предусматривает три примитива активации: привязывание к объектам класса, привязывание к новым экземплярам класса и привязывание к постоянным объектам, хранящимся в файлах. В данной главе детально анализировались первые два из этих примитивов. Третий примитив основан на API-функции СОМ CoGetInstanceFromFile:


HRESULT CoGetInstanceFromFile( [in, unique] COSERVERINFO *pcsi,

// host/security info – информация о хосте/безопасности

[in, unique] CLSID *pClsid,

// explicit CLSID (opt) – явный CLSID (opt)

[in, unique] IUnknown *punk0uter,

// for aggregation – для агрегирования

[in] DWORD dwClsCtx,

// locality? – локализация?

[in] DWORD grfMode,

// file open mode – режим открытия файла

[in] OLECHAR *pwszName,

// file name of object – файловое имя объекта

[in] DWORD cmqi,

// how many interfaces? – сколько интерфейсов?

[out, size_is(cmqi)] MULTI_QI *prgmq

// where to put itfs – куда поместить интерфейсы

);


Эта функция принимает на вход имя файла, которое относится к постоянному состоянию (persistent state) объекта[1]. CoGetInstanceFromFile удостоверяется в том, что объект исполняется, после чего возвращает один или несколько интерфейсных указателей на (ре)активированный объект. Чтобы выполнить эту работу, CoGetInstanceFromFile в первую очередь требуется определить CLSID данного объекта. CLSID требуется по двум причинам. Если объект не исполняется, то CLSID необходим СОМ для создания нового экземпляра, который будет инициализирован от постоянного (находящегося в файле) образа. Во-вторых, если вызывающий объект не указывает определенное хост-имя до запроса на активацию, то СОМ будет использовать CLSID для выяснения того, на какой машине следует активировать объект[2].

Если CLSID не передается явно вызывающим объектом, то CoGetInstanceFromFile извлекает CLSID из самого файла с помощью вызова API-функции СОМ GetClassFile:


HRESULT GetClassFile([in, string) OLECHAR *pwszFileName, [out] CLSID *pclsid);