Сущность технологии СОМ. Библиотека программиста
Добавить в закладки К обложке
- Предисловие Чарли Киндела - Страница 1
- Предисловие Грэйди Буча - Страница 4
- От автора - Страница 5
- Благодарности - Страница 7
- От издательства - Страница 9
- Глава 1. СОМ как улучшенный C++ - Страница 10
- Распространение программного обеспечения и язык С++ - Страница 11
- Динамическая компоновка и С++ - Страница 12
- C++ и мобильность - Страница 13
- Инкапсуляция и С++ - Страница 14
- Отделение интерфейса от реализации - Страница 17
- Абстрактные базы как двоичные интерфейсы - Страница 19
- Полиморфизм на этапе выполнения - Страница 23
- Расширяемость объекта - Страница 25
- Управление ресурсами - Страница 28
- Где мы находимся? - Страница 30
- Глава 2. Интерфейсы - Страница 31
- Снова об интерфейсах и реализациях - Страница 32
- IDL - Страница 33
- Методы и их результаты - Страница 35
- Интерфейсы и IDL - Страница 37
- Интерфейс IUnknown - Страница 39
- Управление ресурсами и IUnknown - Страница 42
- Приведение типов и IUnknown - Страница 45
- Реализация IUnknown - Страница 47
- Использование указателей интерфейса СОМ - Страница 50
- Оптимизация QueryInterface - Страница 52
- Типы данных - Страница 55
- Атрибуты и свойства - Страница 61
- Исключения - Страница 62
- Где мы находимся? - Страница 65
- Глава 3. Классы - Страница 66
- Снова об интерфейсе и реализации - Страница 67
- Объекты классов - Страница 69
- Активация - Страница 71
- Использование SCM - Страница 73
- Классы и серверы - Страница 76
- Обобщения - Страница 81
- Оптимизации - Страница 83
- Снова интерфейс и реализация - Страница 86
- Моникеры и композиция - Страница 89
- Моникеры и сохраняемость - Страница 91
- Время жизни сервера - Страница 93
- Классы и IDL - Страница 95
- Эмуляция классов - Страница 97
- Категории компонентов - Страница 98
- Где мы находимся? - Страница 102
- Глава 4. Объекты - Страница 103
- Снова IUnknown - Страница 104
- QueryInterface симметрична - Страница 105
- QueryInterface транзитивна - Страница 106
- QueryInterface рефлективна - Страница 107
- Объекты имеют статический тип - Страница 108
- Единственность и идентификация - Страница 110
- QueryInterface и IUnknown - Страница 111
- Множественные интерфейсы и имена методов - Страница 113
- Динамическая композиция - Страница 118
- Двоичная композиция - Страница 122
- Включение - Страница 128
- Где мы находимся? - Страница 129
- Глава 5. Апартаменты - Страница 130
- Снова интерфейс и реализация - Страница 131
- Объекты, интерфейсы и апартаменты - Страница 134
- Межапартаментный доступ - Страница 136
- Вспомогательные средства для внутрипроцессного маршалинга - Страница 141
- Архитектура стандартного маршалинга - Страница 144
- Реализация интерфейсных маршалеров - Страница 148
- Стандартный маршалинг, потоки и протоколы - Страница 150
- Управление жизненным циклом и маршалинг - Страница 154
- Специальный маршалинг - Страница 159
- Маршалер свободной поточной обработки (FreeThreaded Marshaler) - Страница 162
- Где мы находимся? - Страница 168
- Глава 6. Приложения - Страница 169
- Подводные камни внутрипроцессной активации - Страница 170
- Активация и SCM - Страница 171
- Снова о времени жизни сервера - Страница 174
- Снова о времени жизни сервера - Страница 178
- Идентификаторы приложений - Страница 182
- COM и защита - Страница 185
- Программируемая защита - Страница 191
- Контроль доступа - Страница 196
- Управление маркерами - Страница 200
- Где мы находимся? - Страница 204
- Разное - Страница 205
- Основы указателей - Страница 206
- Указатели и память - Страница 208
- Массивы - Страница 213
- Управление потоками данных - Страница 221
- Динамический вызов в сравнении со статическим - Страница 224
- Двунаправленные интерфейсные контракты - Страница 227
- Совмещение имен в IDL - Страница 233
- Асинхронные методы - Страница 236
- Где мы находимся? - Страница 237
- Проиложение А. Эволюция объектов - Страница 238
- Приложение Б. Избранный код - Страница 242
Даже несмотря на то, что открытые операторы над типами данных подняты до уровня чисто виртуальных функций в классе интерфейса, клиент не может приписывать значения объектам FastString, не имея определения класса для класса реализации. При демонстрации клиенту определения класса реализации от него будет скрыта двоичная инкапсуляция интерфейса; что не позволит клиенту использовать класс интерфейса. Одним из разумных способов обеспечить клиенту возможность использовать объекты FastString является экспорт из DLL глобальной функции, которая будет вызывать новый оператор от имени клиента. При условии, что эта подпрограмма экспортируется с опцией extern "С" , она будет доступна для любого транслятора C++.

// ifaststring.h
class IFastString {
public:
virtual int Length(void) const = 0;
virtual int Find(const char *psz) const = 0;
};
extern "C"
IFastString *CreateFastString(const char *psz);
// faststring.cpp (part of DLL)
// faststring.cpp (часть DLL)
IFastString *CreateFastString (const char *psz)
{ return new FastString(psz); }
Как было в случае класса-дескриптора, новый оператор вызывается исключительно внутри DLL FastString, а это означает, что размер и расположение объекта будут установлены с использованием того же транслятора, который транслировал все методы реализации.
Последнее препятствие, которое предстоит преодолеть, относится к уничтожению объекта. Следующая клиентская программа пройдет трансляцию, но результаты будут непредсказуемыми:
int f(void)
{
IFastString *pfs = CreateFastString(«Deface me»);
int n = pfs->Find(«ace me»);
delete pfs;
return n;
}
Непредсказуемое поведение вызвано тем фактом, что деструктор класса интерфейса не является виртуальным. Это означает, что вызов оператора delete не сможет динамически найти последний порожденный деструктор и рекурсивно уничтожит объект ближайшего внешнего типа по отношению к базовому типу. Поскольку деструктор FastString никогда не вызывается, в данном примере из буфера исчезнет строка «Deface me», которая должна там присутствовать.
Очевидное решение этой проблемы – сделать деструктор виртуальным в классе интерфейса. К сожалению, это нарушит независимость класса интерфейса от транслятора, так как положение виртуального деструктора в таблице vtbl может изменяться от транслятора к транслятору. Одним из конструктивных решений этой проблемы является добавление к интерфейсу явного метода Delete как еще одной чисто виртуальной функции, чтобы заставить производный класс уничтожать самого себя в своей реализации этого метода. В результате этого будет выполнен нужный деструктор. Модифицированная версия заголовочного файла интерфейса выглядит так:
// ifaststring.h
class IFastString
{
public:
virtual void Delete(void) = 0;
virtual int Length(void) const = 0;
virtual int Find(const char *psz) const = 0;
};
extern "C"
IFastString *CreateFastString (const char *psz);
она влечет за собой соответствующее определение класса реализации:
// faststring.h
#include «ifaststring.h»
class FastString : public IFastString
{ const int mcch;
// count of characters
// счетчик символов
char *mpsz; public: FastString(const char *psz);
~FastString(void);
void Delete(void);
// deletes this instance
// уничтожает этот экземпляр
int Length(void) const;
// returns # of characters
// возвращает число символов
int Find(const char *psz) const;
// returns offset
// возвращает смещение
};
// faststring.cpp
#include <string.h>
#include «faststring.h»
IFastString* CreateFastString (const char *psz) {
return new FastString(psz);
}
FastString::FastString(const char *psz) : mcch(strlen(psz)), mpsz(new char[mcch + 1]) {
strcpy(mpsz, psz);
}
void FastString::Delete(void) {
delete this;
}
FastString::~FastString(void) {
delete[] mpsz;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253