Сущность технологии СОМ. Библиотека программиста
Добавить в закладки К обложке
- Предисловие Чарли Киндела - Страница 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
Динамический вызов в сравнении со статическим
До сих пор говорилось о том, что СОМ основан на клиентских программах, имеющих на этапе разработки предварительную информацию об определении интерфейса. Это достигается либо через заголовочные файлы C++ (для клиентов C++), либо через библиотеки типов (для клиентов Java и Visual Basic). В общем случае это не представляет трудностей, так как программы, написанные на этих языках, перед употреблением обычно проходят фазу какой-либо компиляции. Некоторые языки не имеют такой фазы компиляции на этапе разработки и вместо этого распространяются в исходном коде с тем, чтобы интерпретироваться во время выполнения. Вероятно, наиболее распространенными среди таких языков являются языки сценариев на базе HTML (например, Visual Basic Script, JavaScript), которые выполняются в контексте Web-броузера или Web-сервера. В обоих этих случаях текст сценариев вкладывается в его исходном виде в файл HTML, а окружающая исполняемая программа выполняет текст сценариев «на лету», по мере анализа HTML. С целью обеспечить разнообразную среду программирования эти окружения позволяют сценариям вызывать методы СОМ-объектов, которые могут создаваться в самом тексте сценария или где-нибудь еще в HTML-потоке (например, какой-либо управляющий элемент, который является также частью Web– страницы). В таких средах в настоящее время невозможно использовать библиотеки типов или другие априорные средства для снабжения машины времени выполнения (runtime engine) описанием используемых интерфейсов. Это означает, что объекты сами должны помогать интерпретатору переводить исходный текст сценариев в содержательные вызовы методов.
Для того чтобы объекты быть использованы из интерпретирующих сред типа Visual Basic Script и JavaScript, СОМ определяет интерфейс, выражающий функциональность интерпретатора. Этот интерфейс называется IDispatch и определяется следующим образом:
[object, uuid(00020400-0000-0000-C000-000000000046)] interface IDispatch : IUnknown {
// structure to model a list of named parameters
// структура для моделирования списка именованных параметров
typedef struct tagDISPPARAMS { [size_is(cArgs)] VARIANTARG * rgvarg;
[size_is(cNamedArgs)] DISPID * rgdispidNamedArgs;
UINT cArgs; UINT cNamedArgs;
} DISPPARAMS;
// can the object describe this interface?
// может ли объект описать этот интерфейс?
HRESULT GetTypeInfoCount([out] UINT * pctinfo);
// return a locale-specific description of this interface
// возвращаем специфическое для данной локализации описание этого интерфейса
HRESULT GetTypeInfo( [in] UINT itInfo,
// reserved, m.b.z.
// зарезервировано, должно равняться нулю
[in] LCID lcid,
// locale ID
// код локализации
[out] ITypeInfo ** ppTInfo);
// put it here!
// помещаем это здесь!
// resolve member/parameter names to DISPIDs
// преобразовываем имена членов/параметров в DISPID
HRESULT GetIDsOfNames( [in] REFIID riid,
// reserved, must be IID_NULL
// зарезервировано, должно равняться IID_NULL
[in, size_is(cNames)] LPOLESTR * rgszNames,
// method+params
// метод + параметры
[in] UINT cNames,
// count of names
// количество имен
[in] LCID lcid,
// locale ID
// локальный ID
[out, size_is(cNames)] DISPID * rgid
// tokens of names
// маркеры имен
);
// access member via its DISPID
// обращаемся к члену через его DISPID HRESULT Invoke(
[in] DISPID id,
// token of member
// маркер члена
[in] REFIID riid,
// reserved, must be IID_NULL
// зарезервировано, должно равняться IID_NULL
[in] LCID lcid,
// locale ID
// локальный ID
[in] WORD wFlags,
// method, propput, or propget?
// метод propput или propget?
[in,out] DISPPARAMS * pDispParams,
// logical parameters
// логические параметры
[out] VARIANT * pVarResult,
// logical result
// логический результат
[out] EXCEPINFO * pExcepInfo,
// IErrorInfo params
// параметры IErrorInfo
[out] UINT * puArgErr
// used for type errors
// использовано для ошибок типа
);
Когда машина сценариев впервые пытается обратиться к объекту, она использует QueryInterface для запроса интерфейса IDispatch этого объекта. Если объект отклоняет запрос QueryInterface, то машина сценариев этот объект использовать не может. Если же объект успешно возвращает свой интерфейс IDispatch машине сценариев, то машина будет использовать метод GetIDsOfNames этого объекта для перевода имен методов и свойств в маркеры. Эти маркеры формально называются DISPID и являются эффективно синтаксически разобранными (parsed) целыми числами, которые единственным образом идентифицируют свойство или метод. После преобразования имени метода или свойства в маркер машина сценариев потребует запуска именованного метода/свойства через метод IDispatch::Invoke данного объекта. Отметим, что поскольку IDispatch::Invoke принимает значения параметров операции в виде массива именованных типов VARIANT с использованием структуры DISPPARAMS, то диапазон поддерживаемых типов параметров ограничен возможностью записи в один VARIANT.
- 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