Сущность технологии СОМ. Библиотека программиста
Добавить в закладки К обложке
- Предисловие Чарли Киндела - Страница 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
Отметим, что в приведенном коде программа считывания устанавливает в нуль глобальную переменную g_pStmPtr после демаршалинга. Это сделано потому, что объектная ссылка была маршалирована с флагом MSHLFLAGS_NORMAL и может быть демаршалирована только один раз. Во многих сценариях это не является проблемой. В некоторых других сценариях, однако, желательно маршалировать указатель из одного потока и иметь несколько рабочих потоков, в которых можно демаршалировать интерфейсный указатель по мере необходимости. Если все рабочие потоки выполняются в МТА, то это не является проблемой, поскольку нужно выполнить демаршалинг только в одном потоке – от имени всех потоков, выполняющихся в МТА. Если, однако, рабочие потоки выполняются в произвольных апартаментах, то этот подход не сработает, поскольку тогда придется независимо демаршалировать объектную ссылку в каждом рабочем потоке. Большинство разработчиков в этом случае обращаются к флагу MSHLFLAGS_TABLESTRONG, надеясь на однократный маршалинг и столько демаршалингов, сколько необходимо (по одному разу на апартамент). К сожалению, табличный маршалинг (в отличие от обычного маршалинга) не поддерживается в случае, если исходный указатель является заместителем, что случается часто, особенно в распределенных приложениях. Для разрешения этой проблемы в выпуске СОМ Service Pack 3 под Windows NT 4.0 вводится Глобальная интерфейсная таблипа (Global Interface Table – GIT).
GIT является оптимизацией CoMarshalInterface / CoUnmarshalInterface, которая допускает обращение к интерфейсным указателям из всех апартаментов процесса. Внутри СОМ реализуется одна GIT на процесс. GIT содержит маршалированные интерфейсные указатели, которые могут быть эффективно демаршалированы несколько раз внутри одного и того же процесса. Это семантически эквивалентно использованию табличного маршалинга, однако GIT можно использовать как для объектов, так и для заместителей. GIT выставляет интерфейс IGlobalInterfaceTable:
[uuid(00000146-0000-0000-C000-000000000046), object, local ]
interface IGlobalInterfaceTable : IUnknown {
// marshal an Interface into the GIT
// маршалируем интерфейс в GIT
HRESULT RegisterInterfaceInGlobal ( [in, iid_is(riid)] IUnknown *pItf, [in] REFIID riid, [out] DWORD *pdwCookie);
// destroy the marshaled object reference
// уничтожаем маршалированную объектную ссылку
HRESULT RevokeInterfaceFromGlobal ( [in] DWORD dwCookle);
// unmarshal an interface from the GIT
// демаршалируем интерфейс из GIT
HRESULT GetInterfaceFromGlobal ( [in] DWORD dwCookie, [in] REFIID riid, [out, iid_is(riid)] void **ppv); }
Клиенты получают доступ к GIT для своего процесса, вызывая CocreateInstance с использованием класса CLSID_StdGlobalInterfaceTable. Каждый вызов CoCreateInstance с применением этого CLSID возвращает указатель на одну и ту же GIT в процессе. Так же как к интерфейсу IStream, возвращенному CoMarshalInterThreadInterfaceInStream, к интерфейсным указателям на GIT можно обратиться из любого апартамента без обязательного маршалинга.
Для того чтобы сделать интерфейсный указатель доступным для всех апартаментов процесса, апартамент, содержащий этот интерфейсный указатель, должен зарегистрировать его в GIT путем вызова метода RegisterInterfaceInGlobal. GIT вернет вызывающей программе DWORD, который представляет глобальный указатель для всех апартаментов процесса. Этот DWORD может быть использован из любого апартамента процесса для демаршалинга нового заместителя путем вызова метода GetInterfaceFromGlobal. Этот же DWORD можно использовать для повторного демаршалинга заместителей до тех пор, пока вызов RevokeInterfaceFromGlobal не объявит глобальный интерфейсный указатель недействительным. Приложения, использующие эту глобальную интерфейсную таблицу (GIT ), обычно связывают один интерфейсный указатель на весь процесс при запуске:
- 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