Сущность технологии СОМ. Библиотека программиста | страница 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);