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



Обобщения - часть 2


Хотя такое использование вполне допустимо, интерфейс 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, iid_is(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 позволяют методу возвращать клиенту динамически типизируемый указатель интерфейса.

Предполагая, что объект класса экспортирует интерфейс IClassFactory вместо IApeClass, клиенты должны использовать метод IClassFactory::CreateInstance для создания новых экземпляров :

HRESULT CreateAGorillaAndEatBanana() { IClassFactory *pcf = 0; // find the class object находим объект класса HRESULT hr = CoGetClassObject(CLSID_Gorilla, CLSCTX_ALL, 0, IID_IClassFactory, (void **)&pcf); if (SUCCEEDED(hr)) { IApe *pApe = 0; // use the class object to create a gorilla // используем объект класса для создания gorilla hr = pcf->CreateInstance(0, IID_IApe, (void**)&pApe); // we're done with the class object, so release it // мы закончили с объектом класса, поэтому освобождаем его pcf->Release(); if (SUCCEEDED(hr)) { // tell the new gorilla to eat a banana // приказываем новой горилле есть банан hr = pApe->EatBanana(); pApe->Release(); } } return hr; }




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