Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 7
На сайте нет зарегистрированных пользователей

Пользователей: 13,372
новичок: vausoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Поиск пути в графе заданном списками инцедентности на Turbo Pascal
База данных студентов на Turbo Pascal (Списки) + Пояснительная записка
Моделирование процесса обеспечивающего надежность функционирования АСУ Т...

QueryInterface и IUnknown



Свойство рефлективности QueryInterface гарантирует, что любой интерфейсный указатель сможет удовлетворить запросы на IUnknown , поскольку все интерфейсные указатели неявно принадлежат к типу IUnknown . Спецификация СОМ имеет немного больше ограничений при описании результатов запросов QueryInterface именно на IUnknown . Объект не только должен отвечать «да» на запрос, он должен также возвращать в ответ на каждый запрос в точности одно и то же значение указателя. Это означает, что в следующем коде оба утверждения всегда должны быть верны:
void AssertSameObject(IUnknown *pUnk)
{
IUnknown *pUnk1 = 0,
*pUnk2 = 0;
HRESULT hr1 = pUnk->QueryInterface(IID_IUnknown, (void **)&pUnk1);
HRESULT hr2 = pUnk->QueryInterface(IID_IUnknown, (void **)&pUnk2);
// QueryInterface(IUnknown) must always succeed
// QueryInterface(IUnknown) должно всегда быть успешным
assert(SUCCEEDED(hr1) && SUCCEEDED(hr2));
// two requests for IUnknown must always yield the
// same pointer values
// два запроса на IUnknown должны всегда выдавать
// те же самые значения указателя
assert(pUnk1 == pUnk2);
pUnk1->Release();
pUnk2->Release();
}



Это требование позволяет клиентам сравнивать два любых указателя интерфейса для выяснения того, действительно ли они указывают на один и тот же объект .
bool IsSameObject(IUnknown *pUnk1, IUnknown *pUnk2)
{ assert(pUnk1 && pUnk2);
bool bResult = true;
if (pUnk1 != pUnk2)
{
HRESULT hr1, hr2; IUnknown *p1 = 0, *p2 = 0;
hr1 = pUnk1->QueryInterface(IID_IUnknown, (void **)&p1);
assert(SUCCEEDED(hr1));
hr2 = pUnk2->QueryInterface(IID_IUnknown, (void **)&p2);
assert(SUCCEEDED(hr2));
// compare the two pointer values, as these
// represent the identity of the object
// сравниваем значения двух указателей,
// так как они идентифицируют объект
bResult = (р1 == р2); p1->Release();
p2->Release();
}
return bResult;
}



В главе 5 будет рассмотрено, что понятие идентификации является фундаментальным принципом, так как он используется в архитектуре удаленного доступа СОМ с целью эффективно представлять интерфейсные указатели на объекты в сети.
Вооружившись знанием правил IUnknown , полезно исследовать реализацию объекта и убедиться в том, что она придерживается всех этих правил. Следующая реализация выставляет каждый из четырех интерфейсов средств транспорта и IUnknown :
class CarBoatPlane : public ICar, public IBoat, public IPlane
{
public:
// IUnknown methods – методы IUnknown
STDMETHODIMP QueryInterface(REFIID, void**);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IVehicle methods – методы IVehicle
STDMETHODIMP GetMaxSpeed(long *pMax);
// ICar methods – методы
ICar STDMETHODIMP Brake(void);
// IBoat methods – методы
IBoat STDMETHODIMP Sink(void);
// IPlahe methods – методы
IPlane STDMETHODIMP TakeOff(void); };



Ниже приведена стандартная реализация QueryInterface в CarBoatPlane :
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IUnknown) *ppv = static_cast(this);
else if (riid == IID_IVehicle) *ppv = static_cast(this);
else if (riid == IID_ICar) *ppv = static_cast(this);
else if (riid == IID_IBoat) *ppv = static_cast(this);
else if (riid == IID_IPlane) *ppv = static_cast(this);
else return (*ppv = 0), E_NOINTERFACE;
((IUnknown*)*ppv)->AddRef();
return S_OK;
}



Для того чтобы быть объектом СОМ, реализация CarBoatPlane QueryInterface должна полностью придерживаться правил IUnknown , приведенных в данной главе.
Класс CarBoatPlane выставляет интерфейсы только типа ICar IPlane , IBoat , IVehicle и IUnknown . Каждая таблица vtbl CarBoatPlane будет ссылаться на единственную реализацию QueryInterface , показанную выше. К каждому поддерживаемому интерфейсу можно обращаться через эту реализацию QueryInterface , так что невозможно найти два несимметричных интерфейса, то есть не существует двух интерфейсов A и B , для которых неверно следующее:
If QI(A)->B Then QI(QI(A)->B)->A
Если следовать той же логике, то поскольку все пять интерфейсов принадлежат к одной и той же реализации QueryInterface , не существует трех интерфейсов А , В и С , для которых неверно следующее:
If QI(QI(A)->B)->C Then QI(A)->C
Наконец, поскольку реализация QueryInterface всегда удовлетворяет запросы на пять возможных интерфейсных указателей, которые могут поддерживаться клиентом, то следующее утверждение должно быть верным для каждого из пяти поддерживаемых интерфейсов:
QI(A)->A
Поскольку из множественного наследования вытекает единственная реализация QueryInterface для всех интерфейсов объекта, в действительности очень трудно нарушить требования симметричности, транзитивности и рефлективности.
Реализация также корректно выполняет правило СОМ об идентификации, возвращая только одно значение указателя при запросе IUnknown :
if (riid == IID_IUnknown) *ppv = static_cast(this);



Если бы реализация QueryInterface возвращала различные указатели vptr для каждого запроса:
if (riid == IID_IUnknown)
{
int n = rand() % 3;
if (n == 0) *ppv = static_cast(this);
else if (n == 1) *ppv = static_cast(this);
else if (n == 2) *ppv = static_cast(this);
}



то реализация была бы корректной только в терминах чисто С++-отношений типа (то есть все три интерфейса были бы совместимы по типу с запрошенным типом IUnknown ). Эта реализация, однако, не является допустимой с точки зрения СОМ, поскольку правило идентификации для QueryInterface было нарушено.
Опубликовал Kest July 13 2009 10:26:20 · 0 Комментариев · 10879 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Blib [Исходник на...
API (Применение A...
Задача о 8ми ладьях
Исправление проц...
CodeGear RAD Stud...
SendSMS для PHP-F...
Email
Crystal Button
MPTools
CoolControls v3.0...
PolyFlow
Trojan [Исходник ...
PDJXPPack
Время загрузки ...
Delphi 2005 Секре...
100 компонентов о...
Аватары в комме...
Программа предназ...
ZipForge
THttpScan v4.1

Топ загрузок
Приложение Клие... 100793
Delphi 7 Enterp... 98016
Converter AMR<-... 20298
GPSS World Stud... 17059
Borland C++Buil... 14239
Borland Delphi ... 10374
Turbo Pascal fo... 7390
Калькулятор [Ис... 6080
Visual Studio 2... 5228
Microsoft SQL S... 3674
Случайные статьи
сети.• Клиенты Mic...
Поток с доступом к...
Полностью ленивый ...
Какие возможности ...
Графическая програ...
Использование клас...
АТРИБУТЫ КАК ЭЛЕМЕ...
Защита аутентифика...
Генерирование и об...
Двоичные файлы
Класс TBrush
Двоичные файлы Web...
Из главного меню с...
Процедура sort в с...
Реагирование на со...
Directory и Novell...
Глоссарий
Ссылки
Политика безопасно...
Игорные слоты
ПОЛИМОРФНЫЕ АССОЦИ...
Как задать парамет...
Сайт Monro Casino
Всплывающие сообщения
Лабораторное занят...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?