Сущность технологии СОМ. Библиотека программиста | страница 95



и 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(CLSIDGorilla, CLSCTXALL, 0, IIDIClassFactory, (void **)&pcf);

if (SUCCEEDED(hr))

{

IApe *pApe = 0;

// use the class object to create a gorilla

// используем объект класса для создания gorilla

hr = pcf->CreateInstance(0, IIDIApe, (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;

}


Этот код является семантически идентичным варианту с функцией, которая использовала интерфейс IApeClass вместо интерфейса IClassFactory.

Для того чтобы предыдущий пример работал корректно, объекту класса Gorilla следует реализовать


IClassFactory : class GorillaClass : public IClassFactory

{

public:

IMPLEMENTUNKNOWNNODELETE(GorillaClass)

BEGININTERFACETABLE(GorillaClass)

IMPLEMENTSINTERFACE(IClassFactory)

ENDINTERFACETABLE()

STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)

{

*ppv = 0;

if (pUnkOuter != 0)

// we don't support aggregation yet

// мы еще не поддерживаем агрегирование

return CLASSENOAGGREGATION;

// create a new instance of our C++ class Gorilla

// создаем новый экземпляр нашего С++-класса Gorilla

Gorilla *p = new Gorilla;

if (p == 0) return EOUTOFMEMORY:

// increment reference count by one

// увеличиваем счетчик ссылок на единицу

p->AddRef();