Учебник по Visual C++ .Net


Интерфейсы — основа СОМ-технологии - часть 2


return hr;

else //В случае успеха

//====== Используем указатель для вызова методов:

pMy->SomeMethod();

pMy->Release(); // Освобождаем интерфейс

Возможна и другая тактика:

//====== В случае успеха (определяется макросом)

if (SUCCEEDED(hr))

{

//====== Используем указатель

}

else

{

//====== Сообщаем о неудаче

}

Второй параметр функции Queryinterf асе (указатель на указатель) позволяет возвратить в вызывающую функцию адрес запрашиваемого интерфейса. Примерная схема реализации метода Queryinterf асе (в классе СОМ-объекта, производном от IМу) может иметь такой вид:

HRESULT _stdcall СМу::Queryinterfасе(REFIID id, void **ppv)

{

//=== В *ppv надо записать адрес искомого интерфейса

//=== Пессимистический прогноз (интерфейс не найден)

*ppv = 0;

// Допрашиваем REFIID искомого интерфейса. Если он

// нам не знаком, то вернем отказ E_NOINTERFACE

// Если нас не знают, но хотят познакомиться,

// то возвращаем свой адрес, однако приведенный

// к типу "неизвестного" родителя

if (id == IID_IUnknown)

*ppv = static_cast<IUnknown*>(this);

// Если знают, то возвращаем свой адрес приведенный

// к типу "известного" родителя IМу

else if (id == IID_IMy)

*ppv = static_cast<IMy*>(this);

//===== Иначе возвращаем отказ else

return E_NOINTERFACE;

//=== Если вопрос был корректным, то добавляем единицу

//=== к счетчику наших пользователей

AddRef();

return S_OK;

}

Методы AddRef и Release управляют временем жизни объектов посредством подсчета ссылок (references) на пользователей интерфейса. В соответствии с общей концепцией объект (или его интерфейс) не может быть выгружен системой из памяти, пока не равен нулю счетчик ссылок на его пользователей. При создании интерфейса в счетчик автоматически заносится единица. Каждое обращение к AddRef увеличивает счетчик на единицу, а каждое обращение к Release — уменьшает. При обнулении счетчика объект уничтожает себя сам. Например, так:

ULONG СМу::Release()




Начало  Назад  Вперед



Книжный магазин