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

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

Жанры

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

public ISharkBait,

public IConnectionPointContainer {

LONG m_cRef; // СОM reference count

// счетчик ссылок СОМ

// Surfboards don't support multiple outbound interfaces

// of a given type, so it simply declares single pointers

// of each possible type of callback interface

// Surfboard не поддерживает несколько экспортируемых

// интерфейсов заданного типа, поэтому он просто

// объявляет одиночные указатели каждого возможного

// типа интерфейса обратного вызова

IShutdownNotify *m_pShutdownNotify;

ISurfboardUser *m_pSurfer;

// to deal with identity relationship of IConnectionPoint,

// define an IShutdownNotify-specific nested class + member

//

для работы с отношением тождественности

// IConnectionPoint, определяем специфический для

// IShutdownNotify вложенный класс+член

class XCPShutdownNotify : public IConnectionPoint {

Surfboard *This(void);

// use fixed offset

// испопьзуем постоянное смещение

// IUnknown methods...

// методы IUnknown...

// IConnectionPoint methods...

// методы IConnectionPoint...

} m_xcpShutdownNotify;

// define an ISurfboardUser-specific nested class + member

// определяем специфический для IShutdownNotify вложенный класс+член

class XCPSurfboardUser : public IConnectionPoint {

Surfboard *This(void);

// use fixed offset

// используем постоянное смещение

// IUnknown methods...

// методы IUnknown...

// IConnectionPoint methods...

// методы IConnectionPoint...

} m_xcpSurfboardUser;

// IUnknown methods...

// методы IUnknown...

// ISurfboard methods...

// методы ISurfboard...

// IHazardousDevice methods...

// методы IHazardousDevice...

// ISharkBait methods...

// методы ISharkBait...

// IConnectionPointContainer methods...

// методы IConnectionPointContainer...

};

Следует указать, что экземпляры класса Surfboard будут иметь две отдельные реализации IConnectionPoint, одна из которых используется для присоединения интерфейсов обратного вызова IShutdownNotify, а вторая – для присоединения интерфейсов ISurfboardUser. Эти две реализации разделены на отдельные классы C++, что позволяет каждой реализации IConnectionPoint иметь свои собственные уникальные реализации IUnknown и IConnectionPoint. В частности, может иметься три отдельных реализации QueryInterface со своими собственными наборами интерфейсных указателей, которые могут быть выделены для создания трех отдельных СОМ-копий.

Из приведенного выше определения класса следует такая QueryInterface-peaлизация основного класса Surfboard:

STDMETHODIMP Surfboard::QueryInterface(REFIID riid, void**ppv)

{

if (riid == IID_IUnknown || riid == IID_ISurfboard)

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

else if (riid == IID_IHazardousDevice)

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

else if (riid == IID_ISharkBait)

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

else if (riid == IID_IConnectionPointContainer)

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

else

return (*ppv = 0), E_NOINTERFACE;

((IUnknown*)*ppv)->AddRef;

return S_OK;

}

Отметим, что доступ к интерфейсу IConnectionPoint не может быть осуществлен через эту главную реализацию QueryInterface. Каждый из методов QueryInterface вложенного класса будет выглядеть примерно так:

STDMETHODIMP Surfboard::XCPShutdownNotify::QueryInterface(REFIID riid, void**ppv)

{

if (riid == IID_IUnknown || riid == IID_IConnectionPoint)

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

else

return (*ppv = 0), E_NOINTERFACE;

((IUnknown*)*ppv)->AddRef;

return S_OK;

}

Эту

же реализацию можно было бы применить и к классу XCPSurfboardUser. Между объектом Surfboard и двумя подобъектами, которые реализуют интерфейс IConnectionPoint не существует идентичности.

Для того чтобы объект Surfboard не уничтожил себя раньше времени, подобъекты администратора соединений просто делегируют вызовы своих методов AddRef и Release в содержащий их объект surfboard:

STDMETHODIMP_(ULONG) Surfboard::XCPShutdownNotify::AddRef(void)

{

return This->AddRef;

/* AddRef containing object */

/* AddRef объекта-контейнера */

}

STDMETHODIMP_(ULONG) Surfboard::XCPShutdownNotify::Release(void)

{

return This->Release;

/* Release containing object */

/* Release объекта-контейнера */

}

В приведенных выше методах предполагается, что метод This возвращает указатель на объект-контейнер Surfboard, используя вычисление некоторого постоянного смещения.

Клиенты находят интерфейсы объекта IConnectionPoint посредством вызова метода объекта FindConnectionPoint, который для класса Surfboard мог бы выглядеть примерно так:

STDMETHODIMP Surfboard::FindConnectionPoint(REFIID riid, IConnectionPoint **ppcp)

{

if (riid == IID_IShutdownNotify)

*ppcp = IID_IShutdownNotify;

else if (riid == IID_ISurfboardUser)

*ppcp = &m_xcpSurfboardUser;

else

return (*ppcp = 0), CONNECT_E_NOCONNECTION;

(*ppcp)->AddRef;

return S_OK;

}

Отметим, что объект выдает интерфейсные указатели IConnectionPoint только при запросе тех интерфейсов, на которые он сможет сделать обратный запрос. Необходимо указать также на поразительное сходство с большинством реализации QueryInterface. Основное различие состоит в том, что QueryInterface имеет дело с импортируемыми (inbound) интерфейсами, в то время как FindConnectionPoint – с экспортируемыми (outbound) интерфейсами.

Поскольку метод IConnectionPoint::Advise принимает только интерфейс IUnknown, статически типизированный как интерфейсный указатель обратного вызова [1] , то реализации Advise должны использовать QueryInterface для того, чтобы привязать указатель обратного вызова к соответствующему типу интерфейса:

1 В этом заключается один из известных дефектов в схеме точек стыковки. Другой хорошо известный дефект состоит в том, для каждого типа интерфейса обратного вызова требуется явный вызов FindConnectionPoint. Оба этих дефекта отрицательно сказываются на производительности с связи в увеличением числа полных обходов, которые вносит каждый из этих дефектов. Влияние использования точек стыковки на производительность служит напоминанием, что интерфейсы следует разрабатывать, имея в виду возможный межапартаментиыи доступ.

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

Курсант: назад в СССР

Дамиров Рафаэль
1. Курсант
Фантастика:
попаданцы
альтернативная история
7.33
рейтинг книги
Курсант: назад в СССР

Чужая семья генерала драконов

Лунёва Мария
6. Генералы драконов
Фантастика:
фэнтези
5.00
рейтинг книги
Чужая семья генерала драконов

Пышка и Герцог

Ордина Ирина
Фантастика:
юмористическое фэнтези
историческое фэнтези
фэнтези
5.00
рейтинг книги
Пышка и Герцог

Имперский Курьер. Том 5

Бо Вова
5. Запечатанный мир
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Имперский Курьер. Том 5

Имя нам Легион. Том 7

Дорничев Дмитрий
7. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 7

Возвышение Меркурия

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

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

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

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Вираж бытия

Ланцов Михаил Алексеевич
1. Фрунзе
Фантастика:
героическая фантастика
попаданцы
альтернативная история
6.86
рейтинг книги
Вираж бытия

Отмороженный 11.0

Гарцевич Евгений Александрович
11. Отмороженный
Фантастика:
боевая фантастика
рпг
попаданцы
фантастика: прочее
фэнтези
5.00
рейтинг книги
Отмороженный 11.0

История "не"мощной графини

Зимина Юлия
1. Истории неунывающих попаданок
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
История немощной графини

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Крестоносец

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

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

Призыватель нулевого ранга

Дубов Дмитрий
1. Эпоха Гардара
Фантастика:
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Призыватель нулевого ранга