Навигация
Главная
Поиск
Форум
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
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Содержание сайт... 65535
Вызов хранимых ... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Invision Power ... 65308
Организация зап... 63966
Модуль Forms 60864
Создание отчето... 60740
ТЕХНОЛОГИИ ДОСТ... 57065
Создание потоко... 56436
Пример работы с... 54322
Имитационное мо... 52516
Реклама
Building design suite premium infars.ru.
Сейчас на сайте
Гостей: 11
На сайте нет зарегистрированных пользователей

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

Моделирование вычислительного центра на GPSS + Отчет + Блок схема
Моделирование круглосуточного интернет кафе на GPSS + Отчет
Моделирование работы класса персональных компьютеров на GPSS + Отчет + Б...

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Интерфейс IUnknown



СОМ-интерфейс IUnknown имеет то же назначение, что и интерфейс IExtensibleObject, определенный в предыдущей главе. Последняя версия IExtensibleObject, появившаяся в конце предыдущей главы, имеет вид:
class IExtensibleObject
{
public:
virtual void *Dynamic_Cast(const char* pszType) = 0;
virtual void DuplicatePointer(void) = 0;
virtual void DestroyPointer(void) = 0;
}



Для определения типа на этапе выполнения был применен метод Dynamic_Cast, аналогичный оператору C++ dynamic_cast. Для извещения объекта о том, что указатель интерфейса дублировался, использовался метод DuplicatePointer. Для сообщения объекту, что указатель интерфейса уничтожен и все используемые им ресурсы могут быть освобождены, был применен метод DestroyPointer. Вот как выглядит определение IUnknown на C++:
extern "С" const IID IID_IUnknown: interface IUnknown
{
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv) = 0;
virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
};



Заголовочные файлы SDK дают псевдоним interface ключевому слову C++ struct, используя препроцессор С. Поскольку интерфейсы в СОМ определены не как классы, а как структуры, то для того, чтобы сделать методы интерфейса общедоступными, ключевое слово public не требуется. Чтобы создать для целевой платформы СОМ-совместимые стековые фреймы, необходим макрос STDMETHODCALLTYPE. Если целевыми являются платформы Win32, то при использовании компилятора Microsoft C++ этот макрос раскрывается в _stdcall.
IUnknown функционально эквивалентен IExtensibleObject. Метод QueryInterface используется для динамического определения типа и аналогичен С++-оператору dynamic_cast. Метод AddRef используется для сообщения объекту, что указатель интерфейса дублирован. Метод Release используется для сообщения объекту, что указатель интерфейса уничтожен и все ресурсы, которые объект поддерживал от имени клиента, могут быть отключены. Главное различие между IUnknown и интерфейсом, определенным в предыдущей главе, заключается в том, что IUnknown использует идентификаторы GUID, а не строки для идентификации типов интерфейса на этапе выполнения.
IDL-определение IUnknown можно найти в файле unknwn.idl из директории SDK, содержащей заголовочные файлы:
// unknwn.idl – system IDL file
// unknwn.idl – системный файл IDL
[ local, object, uuid (00000000-0000-0000-C000-000000000046) ] interface IUnknown
{
HRESULT QueryInterface([in] REFIID riid, [out] void **ppv);
ULONG AddRef(void); ULONG Release(void);
}



Атрибут local подавляет генерирование сетевого кода для этого интерфейса. Этот атрибут необходим для того, чтобы смягчить требования СОМ о том, что все методы при вызове с удаленных машин должны возвращать HRESULT. Как будет показано в следующих главах, интерфейс IUnknown трактуется особым образом при работе с удаленными объектами. Заметим, что фактические, то есть использующиеся на практике IDL-описания интерфейсов, которые содержатся в заголовках SDK, немного отличаются от определений, данных в этой книге. Фактические определения часто содержат дополнительные атрибуты для оптимизации генерируемого сетевого кода, которые не имеют отношения к нашему обсуждению. В случае сомнений обратитесь за полными определениями к последней версии заголовочных файлов SDK.
Интерфейс IUnknown является родительским для всех СОМ-интерфейсов. IUnknown – единственный интерфейс СОМ, который не наследует от другого интерфейса. Любой другой допустимый интерфейс СОМ должен быть прямым потомком IUnknown или какого-нибудь другого допустимого интерфейса СОМ, который, в свою очередь, должен сам наследовать или прямо от IUnknown, или от какого-нибудь другого допустимого интерфейса СОМ. Это означает, что на двоичном уровне все интерфейсы СОМ являются указателями на таблицы vtbl, которые начинаются с трех точек входа: QueryInterface, AddRef и Release. Все специфические для интерфейсов методы будут иметь точки входа в vtbl, которые появляются после этих трех общих точек входа.
Чтобы наследовать от интерфейса IDL, нужно или определить базовый интерфейс в том же IDL-файле, или использовать директиву import, чтобы сделать внешнее IDL-определение базового интерфейса явным в данной области действия:
/// calculator.idl
[object, uuid(BDA4A270-A1BA-11dO-8C2C-0080C73925BA)]
interface ICalculator : IUnknown
{
import «unknwn.idl»;
/ bring in def. of IUnknown
// импортируем определение IUnknown
HRESULT Clear(void);
HRESULT Add([in] long n);
HRESULT Sum([out, retval] long *pn);
}



Оператор import может появляться или внутри определения интерфейса, как показано здесь, или предшествовать описанию интерфейса в глобальной области действия. В любом из этих случаев действия оператора import одинаковы, он может многократно импортировать один IDL-файл без всякого ущерба. Поскольку сгенерированный C/C++ заголовочный файл будет требовать С/С++-версии импортируемого IDL-файла, чтобы обеспечить наследование, оператор import из IDL-файла будет странслирован в команду #include в генерируемом заголовочном С/С++-файле:
// calculator.h – generated by MIDL
// calculator.h – генерированный MIDL
// bring in def. of IUnknown
// вводим определения IUnknown
#include «unknwn.h»
extern "C" const IID IID_ICalculator;
interface ICalculator : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE Clear(void) = 0;
virtual HRESULT STDMETHODCALLTYPE Add(long n) = 0;
virtual HRESULT STDMETHODCALLTYPE Sum(long *pn) = 0;
}



Компилятор MIDL также создаст С-файл, содержащий фактические определения всех GUID, имеющихся в исходном IDL-файле:
// calculator_i.с – generated by MIDL
const IID IID_ICalculator =
{ 0xBDA4A270, 0xA1BA, 0x11d0, { 0x8C, 0x2C, 
0x00, 0х80, 0хC7, 0х39, 0x25, 0xBA } };



Каждый проект, который будет использовать этот интерфейс, должен или добавить calculator_i.c к своему файлу сборки (makefile), или включить calculator_i.c в один из исходных файлов на С или C++ с использованием препроцессора С. Если это не сделано, то идентификатору IID_ICalculator не будет выделено памяти для его 128-битного значения и проект не будет скомпонован по причине неразрешенных внешних идентификаторов.
СОМ не накладывает никаких ограничений на глубину иерархии интерфейсов при условии, что конечным базовым интерфейсом является IUnknown. Нижеследующий IDL является вполне допустимым и корректным для СОМ:
import «unknwn.idl»;
[object, uuid(DF12E151-A29A-11d0-8C2D-0080C73925BA)]
interface IAnimal : IUnknown {
HRESULT Eat(void);
}
[object, uuid(DF12E152-A29A-11d0-8C2D-0080C73925BA)]
interface ICat : IAnimal
{
HRESULT IgnoreMaster(void);
}
[object, uuid(DF12E153-A29A-11d0-8C2D-0080C73925BA)]
interface IDog : IAnimal
{
HRESULT Bark(void);
}
[object, uuid(DF12E154-A29A-11d0-8C2D-0080C73925BA)]
interface IPug : IDog
{
HRESULT Snore(void);
}
[object, uuid(DF12E155-A29A-11d0-8C2D-0080C73925BA)]
interface IOldPug : IPug
{
HRESULT SnoreLoudly(void);
}



СОМ накладывает одно ограничение на наследование интерфейсов: интерфейсы СОМ не могут быть прямыми потомками более чем одного интерфейса. Следующий фрагмент в СОМ недопустим:
[object, uuid(DF12E156-A29A-11d0-8C2D-0080C73925BA)]
interface ICatDog : ICat, IDog
{
// illegal, multiple bases
// неверно, несколько базовых интерфейсов
HRESULT Meowbark(void);
}



СОМ запрещает наследование от нескольких интерфейсов по целому ряду причин. Одна из них состоит в том, что двоичное представление результирующего абстрактного базового класса C++ не будет независимым от компилятора. В этом случае СОМ уже не будет являться двоичным стандартом, независимым от разработчика. Другая причина кроется в тесной связи между СОМ и DCE RPC. При ограничении наследования интерфейсов одним базовым интерфейсом преобразование между интерфейсами СОМ и интерфейсными векторами DCE RPC вполне однозначно. В конце концов, отсутствие поддержки нескольких базовых интерфейсов не является ограничением, так как каждая реализация может выбрать для открытия столько интерфейсов, сколько пожелает. Это означает, что основанный на СОМ Cat/Dog по-прежнему допустим на уровне реализации :
class CatDog : public ICat, public IDog
{
//
...
};



Клиент, желающий трактовать объект как Cat/Dog, просто использует QueryInterface для привязки к объекту обоих типов указателей. Если один из вызовов QueryInterface не достигает успеха, то данный объект не является Cat/Dog и клиент может справляться с этим, как сумеет. Поскольку реализации могут открывать несколько интерфейсов, то запрет для интерфейсов наследовать более чем от одного интерфейса является лишь небольшой потерей в смысле семантической информации или информации о типе.
СОМ поддерживает стандарт обозначений, который показывает, какие интерфейсы доступны из объекта. Этот способ придерживается философии СОМ относительно отделения интерфейса от реализации и не раскрывает никаких деталей реализации объекта иначе, чем через список выставляемых им интерфейсов.
Рисунок 2.4 показывает стандартное обозначение класса CatDog. Заметим, что из этой схемы можно сделать единственный вывод: если не произойдет катастрофических сбоев, объекты CatDog выставят четыре интерфейса: ICat, IDog, IAnimal и IUnknown.
Опубликовал Kest July 13 2009 00:35:48 · 0 Комментариев · 7630 Прочтений · Для печати

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


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



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

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

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

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

Пароль



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

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

Случайные загрузки
WinPopup
Java 2 - Эффектив...
Обучение Borland ...
INSTANT BOOSTER v...
WebReg v1.3
CoolHints2k v1.03
Род Стивенс. Delp...
VFW
PHP 5 для "чайников"
С# для профессион...
Усложнённый кальк...
DCMintry
Разработка клиент...
Распознавание тек...
Рисование PopupMenu
Domen Name IP
Введение в станда...
Prolog Interprete...
PHP, MySQL и Drea...
index.php + мод ...

Топ загрузок
Приложение Клие... 100376
Delphi 7 Enterp... 83122
Converter AMR<-... 20046
Borland C++Buil... 11183
GPSS World Stud... 10948
Borland Delphi ... 8130
Turbo Pascal fo... 6973
Visual Studio 2... 4963
Калькулятор [Ис... 4373
FreeSMS v1.3.1 3510
Случайные статьи
Способы обнаружени...
Программа ,имитиру...
Шаблоны классов
Строки - индикатор...
Получение XML-схем...
Унификация
Адресация по базе ...
Устранение избыто...
Общий метод опреде...
Завершение установ...
THEN expected
status
Определение полимо...
Еще один пример ас...
Сегодня ночью я сп...
Общение в ICQ
TopServer
Поля класса
Формат Bmp-файла
14.2. Две важные ф...
Значение доменного...
5.4.1. Запись в ф...
ХАКАЕМ АПОРТ
Модификация источн...
обслуживания конкр...
Статистика



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


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