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



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


Для определения типа объекта, содержащегося в файле, GetClassFile использует информацию из заголовка файла, а также информацию из реестра.

После того как определены класс и хост-машина, СОМ исследует ROT (Running Object Table — таблица исполняющихся объектов) на целевой хост-машине для того, чтобы выяснить, является ли объект уже активированным. Таблица ROT является инструментом SCM, который преобразует произвольные моникеры в экземпляры объектов, исполняющихся на локальной хост-машине. Ожидается, что постоянные объекты будут регистрировать себя в локальной ROT во время загрузки. Чтобы представить файловое имя постоянного объекта в качестве моникера, СОМ предусматривает стандартный тип моникера — файловый моникер, который оборачивает имя файла в интерфейс IMoniker. Файловые моникеры могут создаваться либо путем передачи файлового имени в МkParseDisplayName, либо вызовом явной API-функции CreateFileMoniker:

HRESULT CreateFileMoniker( [in, string] const OLECHAR *pszFileName, [out] IMoniker **ppmk);

Если постоянный объект уже зарегистрировал в ROT свой файловый моникер, то CoGetInstanceFromFile просто возвращает указатель на уже работающий объект. Если же объект в ROT не найден, то СОМ создает новый экземпляр файлового класса и инициализирует его из постоянного объекта с помощью метода IPersistFile::Load этого экземпляра:

[object, uuid(0000010b-0000-0000-C000-000000000046)] interface IPersistFile : IPersist { // called by CoGetInstanceFromFile to initialize object // вызывается функцией CoGetInstanceFromFile для // инициализации объекта HRESULT Load( [in, string] const OLECHAR * pszFileName, [in] DWORD grfMode ); // remaining methods deleted for clarity // остальные методы удалены для ясности }

Реализация объекта отвечает за загрузку из файла всех постоянных элементов и за саморегистрацию в локальной таблице ROT — с целью убедиться, что для каждого файла в каждый момент может исполняться только один экземпляр:

STDMETHODIMP::Load(const OLECHAR *pszFileName, DWORD grfMode) { // read in persisted object state // считываем сохраненное состояние объекта HRESULT hr = this->MyReadStateFromFile(pszFile, grfMode); if (FAILED(hr)) return hr; // get pointer to ROT from SCM // берем указатель на ROT от SCM IRunningObjectTable *prot = 0; hr = GetRunningObjectTable(0, &prot); if (SUCCEEDED(hr)) { // create a file moniker to register in ROT // создаем файловый моникер для регистрации в ROT IMoniker *pmk = 0; hr = CreateFileMoniker(pszFileName, &pmk); if (SUCCEEDED(hr)) { // register self in ROT // саморегистрация в ROT hr = prot->Register(0, this, pmk, &m_dwReg); pmk->Release(); } prot->Release(); } return hr; }




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