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

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

Жанры

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

// этого процесса pfnGCO = LookupInClassTable(rclsid, dwClsCtx);

if (pfnGCO == 0) {

// not loaded yet!

// еще не загружен!

// ask class store or registry for DLL name

// запрашиваем DLL-имя в хранилище классов или в реестре

char szFileName[MAXPATH];

hr = GetFileFromClassStoreOrRegistry(rclsid, dwClsCtx, szFileName);

if (SUCCEEDED(hr))

{

// try to load the DLL and scrape out DllGetClassObject

// пытаемся загрузить DLL и вытащить DllGetClassObject

HINSTANCE hInst = LoadLibrary(szFileName);

if (hInst == 0) return COEDLLNOTFOUND;

pfnGCO = GetProcAddress(hInst,

«DllGetClassObject»);

if (pfnGCO == 0) return COEERRORINDLL;

// cache DLL for later use

// кэшируем DLL для дальнейшего использования InsertInClassTable(rclsid, dwClsCtx, hInst, pfnGCO);

}

}

// call function to get pointer to class object

// вызываем функцию для получения указателя на объект класса

hr = (*pfnGCO)(rclsid, riid, ppv);

}

if ((dwClsCtx & (CLSCTXLOCALSERVER | CLSCTXREMOTESERVER)) && hr == REGDBECLASSNOTREG)

{

// handle out-of-proc/remote request

// обрабатываем внепроцессный/удаленный запрос

}

return hr;

}

Отметим, что реализация CoGetClassObject является единственным местом, откуда вызывается DllGetClassObject . Чтобы укрепить это обстоятельство, компоновщики в модели СОМ выдадут предупреждение в случае, если входная точка DllGetClassObject экспортируется без использования ключевого слова private в соответствующем файле определения модулей:

// from APELIB.DEF

// из APELIB.DEF LIBRARY

APELIB EXPORTS DllGetClassObject private

Фактически в модели СОМ компоновщики предпочитают, чтобы во всех связанных с СОМ точках входа использовалось это ключевое слово.

Обобщения

В предыдущем примере интерфейс IApeClass рассматривался как интерфейс уровня класса, специфический для классов, которые объявляют интерфейс IАре из своих экземпляров. Этот интерфейс позволяет клиентам создавать новые объекты или находить существующие, но в любом случае результирующие объекты должны реализовывать интерфейс IАре . Если бы новый класс хотел разрешить клиентам создавать или находить объекты, несовместимые с IApe , то объект этого класса должен был бы реализовывать другой интерфейс. Поскольку создание и поиск объектов являются общими требованиями, которые большинство классов хотели бы поддерживать, СОМ определяет стандартные интерфейсы для моделирования поиска и создания объектов унифицированным образом (generically). Один стандартный интерфейс для поиска объектов назван IOleItemContainer:

// from oleidl.idl из oleidl.idl

[ object, uuid(0000011c-0000-0000-C000-000000000046) ]

interface IOleItemContainer : IOleContainer {

// ask for object named by pszItem

// запрашиваем объект, именованный

pszItem HRESULT Get0bject(

[in] LPOLESTR pszItem,

// which object? какой объект?

[in] DWORD dwSpeedNeeded,

// deadline

[in, unique] IBindCtx *pbc,

// binding info информация о связывании

[in] REFIID riid,

// which interface? какой интерфейс?

[out, iidis(riid)] void **ppv);

// put it here! разместим его здесь!

// remaining methods deleted for clarity

//

остальные методы удалены для ясности

}

Отметим, что метод GetObject позволяет клиенту задавать тип результирующего интерфейсного указателя. Действительный класс результирующего объекта зависит от контекста и конкретной реализации IOleItemContainer . Следующий пример запрашивает объект класса Gorilla найти объект под именем «Ursus»:

HRESULT FindUrsus(IApe * &rpApe)

{

// bind a reference to the class object

// связываем ссылку с объектом класса

rpApe = 0;

IOleItemContainer *poic = 0;

HRESULT hr = CoGetClassObject(CLSIDGorilla, CLSCTXALL, 0, IIDIOleItemContainer, (void**)&poic);

if (SUCCEEDED(hr))

{

// ask Gorilla class object for Ursus

// запрашиваем объект класса Gorilla на поиск

Ursus hr = poic->GetObject(OLESTR(«Ursus»), BINDSPEEDINDEFINITE, 0, IIDIApe, (void**)&rpApe);

poic->Release;

}

return hr;

}

Хотя такое использование вполне допустимо, интерфейс IOleItemContainer был предназначен для работы в тандеме с моникером элемента (Item Moniker), который будет рассматриваться позже в данной главе.

В СОМ определен еще один стандартный интерфейс для создания объектов. Он называется IClassFactory:

// from unknwn.idl из unknwn.idl

[ object, uuid(00000001-0000-0000-C000-000000000046) ]

interface IClassFactory : IUnknown

{

HRESULT CreateInstance( [in] IUnknown *pUnkOuter, [in] REFIID riid, [out, iidis(riid)] void **ppv) ;

HRESULT LockServer([in] BOOL bLock);

}

Хотя экземпляры класса могли бы экспортировать интерфейс IClassFactory, данный интерфейс обычно экспортируется только объектами класса. Объекты класса не обязаны реализовывать IClassFactory, но, для единообразия, они часто делают это. В момент написания этой книги классы, которые будут встраиваться в среду Microsoft Transaction Server (MTS), должны реализовывать IClassFactory (фактически никакие другие интерфейсы объектов класса не будут распознаваться в MTS).

Интерфейс IClassFactory имеет два метода: LockServer и CreateInstance. Метод LockServer вызывается внутри СОМ во время запроса на внепроцессную активацию и подробно обсуждается в главе 6. Метод CreateInstance используется для запроса на создание объектом класса нового экземпляра класса. Как было в случае IApeClass::CreateApe, тип объекта, который будет подвергаться обработке, определяется объектом класса, которому клиент посылает запрос CreateInstance. Первый параметр CreateInstance используется в агрегировании СОМ и обсуждается в главе 4. Пока же, в рамках третьей главы, для простоты изложения положим этот параметр равным нулю. Второй и третий параметры CreateInstance позволяют методу возвращать клиенту динамически типизируемый указатель интерфейса.

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

Война

Валериев Игорь
7. Ермак
Фантастика:
боевая фантастика
альтернативная история
5.25
рейтинг книги
Война

Экономка тайного советника

Семина Дия
Фантастика:
фэнтези
5.00
рейтинг книги
Экономка тайного советника

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Бестужев. Служба Государевой Безопасности. Книга вторая

Измайлов Сергей
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая

Метатель. Книга 3

Тарасов Ник
3. Метатель
Фантастика:
попаданцы
альтернативная история
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель. Книга 3

Студент из прошлого тысячелетия

Еслер Андрей
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Студент из прошлого тысячелетия

Ты не мой BOY

Рам Янка
5. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ты не мой BOY

Идеальный мир для Лекаря 2

Сапфир Олег
2. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 2

Лекарь для захватчика

Романова Елена
Фантастика:
попаданцы
историческое фэнтези
фэнтези
5.00
рейтинг книги
Лекарь для захватчика

Отверженный VI: Эльфийский Петербург

Опсокополос Алексис
6. Отверженный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Отверженный VI: Эльфийский Петербург

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

Убивать чтобы жить 3

Бор Жорж
3. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 3

Темный Лекарь 11

Токсик Саша
11. Темный Лекарь
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Темный Лекарь 11