Чтение онлайн

на главную - закладки

Жанры

Сущность технологии СОМ. Библиотека программиста
Шрифт:

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;

}

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

3 На практике областью действия ROT является не вся машина, а только Winstation. Это означает, что по умолчанию не все зарегистрированные сессии (logon sessions) получат доступ к объекту. Чтобы убедиться, что объект является видимым для всех возможных клиентов, при вызове IRunningObjectTable::Register объект должен выставить флаг ROTFLAGS_ALLOWANYCLIENT.

Существование 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;

}

может быть упрощена, если вместо этого использовать вызов CoGetObject:

HRESULT GetCornelius(IApe * &rpApe)

{

OLECHAR *pwszObject = OLESTR(\\\\server\\public\\cornelius.chmp);

return CoGetObject(pwszObject, 0, IID_IApe, (void**)&rpApe);

}

Как и в предыдущем случае, когда использовался Class Moniker, уровень изоляции, обеспеченный CoGetObject, позволяет клиенту задавать сколь угодно сложную стратегию активации, не меняя ни единой строки кода.

Время жизни сервера

В предыдущих разделах было показано, как СОМ автоматически загружает DLL с целью перенесения реализации объектов в адресное пространство клиентских программ. Однако пока не обсуждалось, как и когда эти DLL выгружаются. Вообще говоря, серверные DLL могут предотвращать преждевременную выгрузку, но именно клиент выбирает момент, когда DLL фактически перестают использоваться. Клиенты, желающие освободить неиспользуемые DLL, вызывают API-функцию СОМ CoFreeUnusedLibraries:

void CoFreeUnusedLibraries(void);

Обычно эта подпрограмма вызывается клиентами в свободное время с целью собрать мусор в своем адресном пространстве. При вызове CoFreeUnusedLibraries СОМ опрашивает каждую из загруженных DLL, чтобы выявить, какие из них не используются. Это делается посредством вызова в каждой DLL функции DllCanUnloadNow, которая должна быть явно экспортирована из этой динамически подключаемой библиотеки.

Функция DllCanUnloadNow, которую экспортирует DLL каждого сервера, должна соответствовать следующей сигнатуре:

HRESULT DllCanUnloadNow(void);

Если DLL желает быть освобожденной, то она возвращает S_OK. Если DLL хочет остаться загруженной, то она возвращает S_FALSE. Серверные DLL должны оставаться загруженными по крайней мере до тех пор, пока сохраняются интерфейсные указатели на ее объекты. Это означает, что в DLL должен быть счетчик всех существующих ссылок на объекты. Чтобы упростить реализацию этого, большинство DLL содержат одну переменную для счетчика блокировок (lock count) и используют две функции для автоматического инкрементирования и декрементирования этого счетчика:

Поделиться:
Популярные книги

Эволюционер из трущоб. Том 4

Панарин Антон
4. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 4

Измена. Возвращение любви!

Леманн Анастасия
3. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Возвращение любви!

Газлайтер. Том 14

Володин Григорий Григорьевич
14. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 14

Вперед в прошлое 2

Ратманов Денис
2. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 2

Адвокат вольного города 3

Кулабухов Тимофей
3. Адвокат
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Адвокат вольного города 3

Черный Маг Императора 7 (CИ)

Герда Александр
7. Черный маг императора
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 7 (CИ)

Шайтан Иван 2

Тен Эдуард
2. Шайтан Иван
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Шайтан Иван 2

На границе империй. Том 8

INDIGO
12. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8

Измена. Жизнь заново

Верди Алиса
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Жизнь заново

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Око василиска

Кас Маркус
2. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Око василиска

Жена моего брата

Рам Янка
1. Черкасовы-Ольховские
Любовные романы:
современные любовные романы
6.25
рейтинг книги
Жена моего брата

Государь

Кулаков Алексей Иванович
3. Рюрикова кровь
Фантастика:
мистика
альтернативная история
историческое фэнтези
6.25
рейтинг книги
Государь

Законы Рода. Том 8

Flow Ascold
8. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 8