COM
|
- Сколько нужно сотрудников службы поддержки компании Microsoft, чтобы заменить лампочку?
- Четыре. Первый, чтобы узнать регистрационный номер лампочки. Второй, чтобы спросить: "А вы перезагрузиться пробовали?" Третий, чтобы спросить: "А вы пробовали её переустановить?" И четвёртый, чтобы сказать: "Это у вас что-то с железом. У нас в офисе лампочка работает отлично!"
|
COM расшифровывается как "Component Object Model" - Модель Компонентных
Объектов. Это стандарт, описывающий как должны работать интерфейсы класса (или
объекта) -- включая такие вопросы, как, например, работа с памятью или
многопоточностью, и каким образом приложения могут использовать компоненты,
созданные в стандарте COM. COM является стандартом, независимым от языка
программирования и (по крайней мере, как это понял я) независимым от аппаратного
окружения. Первоначально стандарт был разработан, опубликован и принят фирмами
Microsoft и IBM, но пока не существует технической причины для того, чтобы он не
поддерживался, например, и на Sun Sparc20 под управлением операционной системы
Solaris.
Вот отличительные признаки и основные механизмы функционирования
COM-объекта:
- У него имеется "globally unique identifier" (глобальный уникальный
идентификатор) -- сокращенно GUID или CLSID -- 128-битное целое число, которое,
по существу, должно гарантировать уникальность COM-объекта (или интерфейса в
случае CLSID) на всех компьютерах нашей планеты. Для того, чтобы воспользоваться
COM-объектом, клиенту необходимо знать его GUID.
- Если клиенту известен GUID COM-объекта, то для создания его экземпляра можно
воспользоваться стандартным API вызовом CoCreateInstance.
- Объект содержит по крайней мере один интерфейс с именем IUnknown. IUnknown
имеет три метода: AddRef, Release и QueryInterface. AddRef и Release вызываются
клиентами для управления счетчиком ссылок, в котором хранится количество
используемых ссылок на объект. Как только счетчик ссылок будет равен нулю,
объект будет удален из памяти.
Клиент может вызвать QueryInterface для того, чтобы определить, поддерживает
ли объект специфический интерфейс (интерфейс - группа свойств и методов). Если
это так, QueryInterface возвращает ссылку на таблицу указателей свойств и
методов, поддерживаемых интерфейсом. После это клиент может вызывать эти методы,
используя указатели, получаемые из таблицы.
OLE - "развивающийся стандарт" (который, вероятно, в нашем контексте можно
назвать "перемещающий цели"), созданный для предоставления комплекса услуг
(компонентам, приложениям и др.) с применением COM-ориентированных объектов.
Автоматизация OLE является отдельным OLE-сервисом, предоставляющим клиенту
возможность управления отдельными компонентами. Действительно, это несколько
непривычно. Компонент, которым можно управлять с помощью OLE автоматизации,
называется IDispatch. IDispatch включает методы для определения поддерживаемых
интерфейсом методов (извините за каламбур), их имен, типов данных, описание всех
параметров и специальный "dispatch ID" для каждого метода интерфейса. Если
клиент знает имя метода, то с помощью IDispatch он может узнать о нем все.
Конечно, это займет какое-то время, но это работает. Конечно лучше, когда он
заранее знает (например, во время компиляции) dispID и информацию о параметрах
вызываемого метода для его непосредственного вызова во время выполнения
программы через метод IDispatch Invoke.
Для вызовов всех методов объекта программа использует интерфейс объектов
IDispatch (и/или библиотеку типов) для определения dispID и информации о
параметрах, и при компиляции вставляет эту информацию в вашу программу. Это так
называемое "раннее связывание", позволяющее осуществлять максимально быстрые
вызовы методов COM-объектов при использовании OLE автоматизации. Вы можете также
воспользоваться "поздним связыванием", когда программа для определения dispID,
имени метода и пр. использует IDispatch только во время ее выполнения. Это
случается при использовании объектной переменной, объявленной "как объект" ("As
Object"). Позднее связывание достаточно медленное и отчасти ненадежное
(поскольку во время компиляции программа не может осуществить проверку
параметров), но может иногда применяться ввиду своей гибкости.
|