Сущность технологии СОМ. Библиотека программиста
Добавить в закладки К обложке
- Предисловие Чарли Киндела - Страница 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
return mcch;
// return cached length
// возвращает скрытую длину
}
Сделав эти три модификации, разработчик библиотеки может теперь перестроить DLL FastString и сопутствующий ей набор тестов, которые полностью проверяют каждый аспект класса FastString . Разработчик будет приятно удивлен, узнав, что принцип инкапсуляции обошелся ему дешево, и в исходных текстах тестов не понадобилось делать никаких изменений. После проверки того. что новая DLL работает правильно, разработчик библиотек отсылает FastString версии 2.0 клиенту, будучи уверенным, что вся работа завершена.
Когда клиенты, заказавшие изменения, получают модернизированный FastString , они включают новое определение класса и DLL в систему контроля своего исходного кода и запускают тестирование нового и улучшенного FastString . Подобно разработчику библиотеки, они тоже приятно удивлены: для того, чтобы воспользоваться преимуществами новой версии Length , не требуется никаких модификаций исходного кода. Вдохновленная этим опытом, команда разработчиков убеждает начальство включить новую DLL в окончательный «золотой» CD, уже готовый для выпуска. Это тот редкий случай, когда руководство идет навстречу энтузиастам-разработчикам и включает в окончательный продукт новую DLL. Подобно большинству программ инсталляции, описание установки клиентской программы настроено на молчаливое (без предупреждения) замещение всех старых версий FastString DLL, какие есть на машине конечного пользователя. Это выглядит вполне безобидно, поскольку эти изменения не затронули открытый интерфейс класса, так что тотальная молчаливая модернизация под версию 2.0 FastString только улучшит любые имеющиеся клиентские приложения, которые были установлены раньше.
Представим себе следующий сценарий: конечные пользователи наконец-то получают свои экземпляры вожделенного продукта. Каждый из них тут же бросает все и устанавливает новое приложение на свою машину, дабы попробовать его. После того как высохли слезы восторга от того, что наконец-то можно делать быстрый текстовый поиск, пользователь возвращается к его или ее нормальному состоянию и запускает ранее установленное приложение, которое также имеет неосторожность использовать DLL FastString. Первые несколько минут всё идет хорошо. Затем внезапно появляется сообщение, что возникла исключительная ситуация и что вся работа конечного пользователя пропала. Он пытается запустить приложение снова, но на этот раз диалоговое окно об исключительной ситуации появляется почти сразу. Конечный пользователь, привычный к употреблению современного программного обеспечения, переустанавливает операционную систему и все приложения, но даже это не спасает от повторения исключительной ситуации. Что же произошло?
А произошло то, что разработчик библиотеки был убаюкан верой в то, что C++ поддерживает инкапсуляцию. Хотя C++ и поддерживает синтаксическую инкапсуляцию через свои закрытые и защищенные ключевые слова, в стандарте C++ ничего не сказано о двоичной инкапсуляции. Это происходит потому, что модель трансляции C++ требует, чтобы клиентский компилятор имел доступ ко всей информации относительно двоичного представления объектов, – с целью обработать экземпляр класса или делать невиртуальные вызовы метода. Это включает в себя информацию о размере и порядке закрытых и защищенных элементов данных объекта. Рассмотрим сценарий, показанный на рис. 1.3. Версия 1.0 FastString требует четыре байта на экземпляр (принимая sizeof(char *) == 4). Клиенты написанного под версию 1.0 определения класса выделяют четыре байта памяти под вызов конструктора класса. Конструктор, деструктор и методы версии 2.0 (а именно эти версии содержатся в DLL в машине конечного пользователя) ожидают, что клиент выделил восемь байт на экземпляр (принято sizeof(int) == 8), и не предусматривают собственных резервов для записи во все восемь байт. К сожалению, у клиентов с версией 1.0 вторые четыре байта этого объекта на самом деле принадлежат кому-то другому, и запись в это место указателя на текстовую строку недопустима, о чем и сообщает диалог исключительной ситуации.
Существует общее решение проблемы версий – переименовывать DLL всякий раз, когда появляется новая версия. Такая стратегия принята в Microsoft Foundation Classes (MFC). Когда номер версии включен в имя файла DLL (например, FastString10.DLL, FastString20.DLL), клиенты всегда загружают ту версию DLL, с которой они были сконфигурированы, независимо от присутствия в системе других версий. К сожалению, со временем, из-за недостаточного опыта в системном конфигурировании, число версий DLL, имеющихся в системе конечного пользователя, может превысить реальное число пользовательских приложений. Чтобы убедиться в этом, достаточно проверить системный каталог любого компьютера, проработавшего больше шести месяцев.
- 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