Сущность технологии COM



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


Метод IPersistFile::Load нового созданного экземпляра будет вызван диспетчером SCM во время выполнения CoGetInstanceFromFile. В приведенном выше примере для получения указателя на интерфейс IRunningObjectTable в SCM используется API-функция СОМ GetRunningObjectTable. Этот интерфейс затем используется для регистрации своего моникера в ROT, так что последующие вызовы CoGetInstanceFromFile, использующие то же файловое имя, не будут создавать новые объекты, а вместо этого возвратят ссылки на этот объект.

Существование File Moniker обусловлено двумя причинами. Во-первых, он нужен, чтобы позволить объектам самим регистрироваться в ROT, чтобы их мог найти CoGetInstanceFromFile. Во-вторых, чтобы скрыть от клиента использование CoGetInstanceFromFile за интерфейсом IMoniker. Реализация File Moniker из BindToObject просто вызывает CoGetInstanceFromFile:

// pseudo-code from OLE32.DLL // псевдокод из OLE32.DLL

STDMETHODIMP FileMoniker::BindToObject(IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppv) { // assume failure - на случай сбоя *ppv = О; HRESULT hr = E_FAIL; if (pmkToLeft == 0) { // no moniker to left - слева моникеров нет MULTI_QI mqi = { &riid, 0, 0 }; COSERVERINFO *pcsi; DWORD grfMode; DWORD dwClsCtx; // these three parameters are attributes of the BindCtx // эти три параметра являются атрибутами BindCtx this->MyGetFromBindCtx(pbc, &pcsi, &grfMode, &dwClsCtx); hr = CoGetInstanceFromFile(pcsi, 0, 0, dwClsCtx, grfMode, this->m_pszFileName, 1, &mqi); if (SUCCEEDED(hr)) *ppv = mqi.pItf; } else { // there's a moniker to the left - слева есть моникер // ask object to left for IClassActivator // or IClassFactory // запрашиваем объект слева от IClassActivator или от // IClassFactory } return hr; }

При таком поведении File Moniker следующая функция, вызывающая CoGetInstanceFromFile

HRESULT GetCornelius(IApe * &rpApe) { OLECHAR *pwszObject = OLESTR("\\\\server\\public\\cornelius.chmp"); MULTI_QI mqi = { &IID_IApe, 0, 0 }; HRESULT hr = CoGetInstanceFromFile(0, 0, 0, CLSCTX_SERVER, STCM_READWRITE, pwszObject, 1, &mqi); if (SUCCEEDED(hr)) rpApe = mqi.pItf; else rpApe = 0; return hr; }




Содержание  Назад  Вперед