1.2.1 Разработка приложений на основе COM

Во все времена одной из актуальнейших задач, стоящих перед разработчиками ПО, было обеспечение взаимодействия между отдельными программами. Для ее решения используется целый арсенал различных способов и приемов.

На заре существования Windows были внедрены разделяемые файлы, буфер обмена и технология динамического обмена данными (Dynamic Data Exchange, DDE).

Для обеспечения обмена данными и предоставления служб был разработан первый вариант технологии связывания и внедрения объектов Object Linking and Embedding – OLE 1. она предназначалась для создания составных документов – того, к чему мы все уже давно привыкли. Эта технология была во многом несовершенной, и на смену ей пришла технология OLE 2. Она предоставляет способ решения более общей проблемы – как научить разные программы предоставлять друг другу собственные функции (службы) и как научить их правильно использовать эти функции.

Для решения этой проблемы помимо OLE был разработан целый ряд технологий. В основе этих разработок лежит базовая технология Component Object Model (COM) – Многокомпонентная Модель Объектов. Она описывает способ взаимодействия программ любого типа. Одна часть ПО предоставляет для использования собственные службы, а другая получает к ним доступ. При этом совершенно не важно, где расположены эти части – в одном процессе, в разных процессах на одном компьютере или на разных компьютерах.

Для созданных на основе спецификаций COM приложений также неважно, какой язык программирования использовался при их разработке – если стандарт COM соблюден, взаимодействие осуществляется без помех.

В настоящее время COM используется в самых различных областях разработки ПО. На основе COM разработаны технологии Автоматизации (Automation), ActiveX, ActiveForm Microsoft Transaction Server.

В составе Delphi работают две динамические библиотеки OLE32.dll OLEAUT32.dll, которые содержат базовые интерфейсы и общие функции COM.

COM – это технология, позволяющая объектам взаимодействовать, несмотря на границы процесса или машины, так же легко, как и объектам внутри одного процесса. COM обеспечивает такое взаимодействие, определяя, что единственный путь управления данными, ассоциированными с объектом, лежит через интерфейс объекта. Термин «интерфейс», о котором речь пойдет чуть ниже, означает реализацию в коде COM-совместимого двоичного интерфейса, ассоциированного с объектом.

СОМ – общая технология взаимодействия объектов стандартизующая как сами объекты, так и методы их взаимодействия. Это спецификация, строящаяся на базе эталонных реализаций. COM является платформно-независимой, объектно-ориентированной технологией, позволяющей создавать бинарные компоненты. Эти компоненты можно использовать как локально, так и в распределенном сетевом окружении. COM служит основой для: OLE (технология составных документов), ActiveX-объектов и элементов управления ActiveX, DCOM, COM+.

DCOM (Distributed COM) – это расширение COM, делающее эту модель распределенной, то есть позволяющей вызывать COM-объекты, находящиеся на другом компьютере в сети.

COM+ – это эволюция COM и MTS. COM+ полностью встроен в Windows 2000. Он существенно расширяет возможности своих предшественников. COM+ обратно совместим с DCOM, MTS и COM, и позволяет создавать распределенные приложения, клиентские части которых можно запускать на старых ОС (Windows 9x и Windows NT).

Напомним, что в модели COM все основано на интерфейсах. Интерфейс - это контракт между реализующим данный интерфейс компонентом и клиентом, представленный набором определений методов (ничего кроме определений методов в интерфейс включать нельзя). Один и тот же интерфейс могут реализовать различные компоненты, написанные на разных языках, но любой компонент, реализующий данный интерфейс, гарантирует полную реализацию его семантики, т.е. определенный набор методов.

COM-объект

В технологии COM приложение предоставляет для использования свои службы, применяя для этого объекты COM. Одно приложение содержит как минимум один объект. Каждый объект имеет один или несколько интерфейсов. Каждый интерфейс объединяет методы объекта, которые обеспечивают доступ к свойствам (данным) и выполнение операций. Обычно в интерфейсе объединяются все методы, выполняющие операции одного типа или работающие с однородными свойствами.

Клиент получает доступ к службам объекта только через интерфейс и его методы. Этот механизм является ключевым. Клиенту достаточно знать несколько базовых интерфейсов, чтобы получить исчерпывающую информацию о составе свойств и методов объекта. Поэтому любой клиент может работать с любым объектом, независимо от их среды разработки. Согласно спецификации COM, уже созданный интерфейс не может быть изменен ни при каких обстоятельствах. Это гарантирует постоянную работоспособность приложений на основе COM, невзирая на любые модернизации.

Объект всегда работает в составе сервера COM. Сервер может быть динамической библиотекой или исполняемым файлом. Объект может иметь собственные свойства и методы или использовать данные и службы сервера.

Для доступа к методам объекта клиент должен получить указатель на соответствующий интерфейс. Для каждого интерфейса существует собственный указатель. После чего клиент может использовать службы объекта, просто вызывая его методы. Доступ к свойствам объектов осуществляется только через его методы.

Предположим, что объект COM встроен в электронную таблицу и обеспечивает доступ к математическим операциям. Будет логично разделить математические функции на группы по типам и создать для каждой группы собственный интерфейс. Например, можно выделить линейные, тригонометрические, агрегатные функции и т.д. На рис. 1. объект расположен внутри сервера – электронной таблицы. Интерфейсы обозначены кружками, связанными с объектом. Пусть интерфейс линейных функций называется ILinear, а интерфейс агрегатных функций –IAggregate.

Объект СОМ – это некоторая сущность, имеющая состояние и методы доступа, позволяющие изменять это состояние. СОМ-объекты можно создавать прямым вызовом специальных функций, но напрямую уничтожить его невозможно. Вместо прямого уничтожения используется механизм самоуничтожения, основанный на подсчете ссылок. Самым близким аналогом в объектно-ориентированных языках программирования является понятие объекта в языке Java.

Так, в COM присутствует понятие класса. Класс в COM носит название CoClass.



Рис. 1. Сервер, объект и его интерфейсы

Согласно правилам обозначения объектов COM, базовый интерфейс IUnknown, который имеется у любого объекта, обозначается как кружок, примыкающий к верхней стороне прямоугольника объекта. Остальные интерфейсы обозначаются справа и слева.


Рис.2. Схема взаимодействия клиента и объекта COM

Чтобы получить доступ к агрегатной функции расчета среднего, клиент должен получить указатель на интерфейс IAgregate, а затем обратится к этой функции.

Взаимодействие между клиентом и объектом обеспечивается базовыми механизмами COM. При этом от клиента скрыто, где именно расположен объект: в адресном пространстве того же процесса, в другом процессе или на другом компьютере. Поэтому с точки зрения разработчика клиентского ПО использование функций электронной таблицы выглядит как обычное обращение к методу объекта. Механизм обеспечения взаимодействия между удаленными элементами COM называется маршалингом (marshalling).

Возникает вопрос – как происходит создание и инициализация объекта COM при первом обращении клиента? Сомнительно, чтобы ОС самостоятельно создавала экземпляры всех зарегистрированных в ней классов в надежде, что один их них понадобится. А ведь для работы объекта требуются еще и серверы. Представьте, что каждый раз при загрузке Windows настойчиво запускает Word, excel, Internet Explorer и т.д.

Любой объект COM является обычным экземпляром некоторого класса, описывающего его свойства и методы. Информация обо всех зарегистрированных и доступных в данной ОС классах COM собрана в специальной библиотеке COM, которая используется для запуска экземпляра класса – объекта.

Сначала объект обращается к библиотеке COM, передавая ей имя требуемого класса и необходимого в первую очередь интерфейса. Библиотека находит нужный класс и сначала запускает сервер, который затем создает объект – экземпляр класса. После этого библиотека возвращает клиенту указатели на объект и интерфейс. В последующей работе клиент может обращаться непосредственно к объекту и его интерфейсам.

После создания наступает очередь инициализации – объект должен загрузить необходимые данные, считать настройки из системного реестра и т.д. за это отвечают специальные объекты COM, которые называются моникерами (monikers). Они работают скрытно от клиента. Обычно моникер создается вместе с классом.

Довольно реальной представляется ситуация, когда одновременно несколько клиентов обращаются к одному объекту. При соответствующих настройках для каждого клиента создается отдельный экземпляр класса. За выполнение этой операции отвечает специальный объект COM, который называется фабрикой класса.

Наконец, остался не рассмотренным последний вопрос – как клиент может получить информацию об объекте. Например, разработчик клиентского ПО знает, что электронная таблица создана в соответствии со спецификацией COM, но не имеет понятия об объектах COM, которые предоставляют клиентам ее службы. Для разрешения подобных ситуаций разработчик объекта COM может распространять вместе с объектом информацию о типе. Она включает сведения об интерфейсах, их свойствах и методах, параметрах методов.

Эта информация содержится в библиотеке типов, которая создается при помощи специального языка описания интерфейса (Interface Definition Language, IDL).

Объект

Центральным элементом COM является объект. Приложения, поддерживающие COM, имеют в своем составе один или несколько объектов COM. Каждый объект представляет собой экземпляр соответствующего класса и содержит один или несколько интерфейсов. Что же такое объект COM?

Любой объект является экземпляром некоторого класса, т.е. представляет собой переменную объектного типа. Поэтому объект обладает набором свойств и методов, которые работают с этими свойствами. К объектам применимы три основные характеристики: инкапсуляция, наследование и полиморфизм. Объекты COM всем этим требованиям удовлетворяют.

Применительно к объектам вообще понятие интерфейса объекта, как он был определен выше, не используется. В первом приближении можно считать, что все методы объекта составляют его единственный интерфейс, а указателем интерфейса является указатель на объект.

Объект COM может иметь любое число интерфейсов (если это число больше нуля), причем каждый интерфейс обладает собственным указателем. Это первое отличие объектов COM от обычных.

У объектов COM имеется особенность еще в одном объектом механизме – наследовании. Вообще различают два способа наследования. Наследование реализации подразумевает передачу родителем потомку всего программного кода. Наследование интерфейса означает передачу только объявления методов, их программный код потомок должен предоставить самостоятельно.

Объекты COM поддерживают только наследование интерфейса, избегая тем самым возможного нарушения инкапсуляции родителя. Тем не менее, просто так выбросить наследование реализации нельзя. Вместо нее объекты COM используют механизм включения, т.е. при необходимости потомок вызывает нужный метод родителя. Также применяется механизм агрегирования, когда один или несколько интерфейсов одного объекта на время включаются в другой объект путем передачи указателей.

Интерфейс

Если объект COM является ключевым элементом реализации COM, то интерфейсы являются центральным звеном идеологии COM. Как двум принципиально разным объектам обеспечить взаимодействие друг с другом? Ответ прост: им необходимо заранее договорится о том, как они будут общаться.

Интерфейс как раз является тем средством, которое позволяет клиенту правильно обратиться к объекту COM, а объекту ответить так, чтобы клиент его понял.

Рассмотрим небольшой пример. На улице случайно встретились два человека: местный житель (объект COM) и заблудившийся иностранец (клиент). Предусмотрительный иностранец взял с собой словарь (библиотека типов или интерфейс IUnknown). Иностранцу нужны знания местного жителя о городе. Он достал ручку и бумагу и, заглянув в словарь, составил фразу и старательно перерисовал незнакомые слова на бумагу. Местный житель оказался не промах. Он прочитал фразу, отобрал у иностранца словарь, составил по нему собственную фразу и тоже написал ее на бумаге. И все закончилось хорошо: довольный клиент (иностранец) получил от объекта COM (местного жителя) результат работы службы (информацию о дороге), а местный житель ушел вместе со словарем.

Как вы уже догадались, в этом примере интерфейсом является бумага и ручка: иностранец не знает чужого языка, зато знает, как правильно спросить, чтобы ему ответили.

Для идентификации каждый интерфейс имеет два атрибута. Во-первых, это его имя, составленное из символов в соответствии с правилами используемого языка программирования. Каждое имя должно начинаться с символа «I». Это имя используется в программном коде. Во-вторых, это глобальный уникальный идентификатор (Globally Unique IDentifer, GUID), который представляет собой гарантированно уникальное сочетание символов, практически не повторяемое ни на одном компьютере в мире. Для интерфейсов такой идентификатор носит название IID (Interface Identifier).

В общем случае клиент может не знать, какие интерфейсы имеются у объекта. Для получения их перечня используется базовый интерфейс IUnknown., который есть у любого объекта COM.

Затем клиенту необходимо знать, какие методы имеет выбранный им интерфейс. Для этого разработчик должен распространять описание методов интерфейсов вместе с объектом. Эту задачу помогает решать язык IDL (он также используется в библиотеках типов).

Теперь осталось сделать самое важное – правильно вызвать сам метод. Для этого в COM описана реализация интерфейса на основе стандартного двоичного формата. Это обеспечивает независимость от языка программирования.



Рис.3. Формат интерфейса COM

Доступный клиенту указатель интерфейса ссылается на внутренний указатель объекта и, через него, на специальную виртуальную таблицу. Эта таблица содержит указатели на все методы интерфейса.

В результате, вызов метода клиентом проходит по цепочке указателей и получает указатель на конкретный метод, а затем исполняется соответствующий программный код.

Реализация интерфейса (interface implementation) – это код, который программист создает для выполнения действий, оговоренных в определении интерфейса. Реализации интерфейсов, помещенные в COM-библиотеки или exe-модули, могут использоваться при создании объектно-ориентированных приложений. Разумеется, программист может игнорировать эти реализации и создать собственные. Интерфейсы ассоциируются с CoClass’ами. Чтобы воспользоваться реализацией функциональности интерфейса, нужно создать экземпляр объекта соответствующего класса, и запросить у этого объекта ссылку на соответствующий интерфейс.

CoClass CoClass – это класс, поддерживающий набор методов и свойств (один или более), с помощью которых можно взаимодействовать с объектами этого класса. Такой набор методов и свойств называется интерфейсом (Interface).

Каждый CoClass имеет два идентификатора – один из них, текстовый, называется ProgID и предназначен для человека, а второй, бинарный, называется CLSID.

CLSID является глобально уникальным идентификатором (GUID). GUID имеет размер 128 бит и уникален в пространстве и времени. Его уникальность достигается путем внедрения в него информации об уникальных частях компьютера, на котором он был создан, таких, как номер сетевой карты, и времени создания с точностью до миллисекунд. Эта технология, как и большинство других базовых концепций в СОМ, позаимствована из OSF DCE RPC. С помощью CLSID можно точно указать, какой именно объект требуется. Тип данных GUID применяется и для идентификации COM-интерфейсов. В этом случае он называется IID. Сгенерировать новое значение типа GUID можно с помощью API-функции Win32 CoCreateGuid. На практике использовать эту функцию приходится не часто, так как современные средства разработки полностью автоматизируют эту задачу, а VB вообще скрывает от программиста такие тонкости, как работу с CLSID и IID.

Для создания экземпляра объекта используется CLSID. Если имеется только ProgID CoClass’а или CLSID в строковом виде ("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} ", где X – шестнадцатеричная цифра), то CLSID можно получить, вызвав функцию CLSIDFromString. Для случая с ProgID информация о CoClass’е должна содержаться в реестре машины, на которой производится вызов функции. В реестр информация заносится автоматически при регистрации объекта (во время процедуры инсталляции или при компиляции).

Перевести CLSID, IID или любой другой GUID в строку можно с помощью функции StringFromGUID2. Как уже говорилось выше, практически все необходимые GUID генерируются автоматически, но при необходимости можно сгенерировать GUID вручную, с помощью утилиты guidgen.

Программист никогда не взаимодействует с объектом и его данными напрямую. Для этого используются интерфейсы объектов.

Интерфейс IUnknown

Каждый объект COM обязательно имеет интерфейс IUnknown. Этот интерфейс имеет всего три метода, но они играют ключевую роль в функционировании объекта.

Метод QueryInterface возвращает указатель на интерфейс объекта, идентификатор IID которого передается в параметре метода. Если такого интерфейса объект не имеет, метод возвращает null.

Обычно при первом обращении к объекту клиент получает указатель на интерфейс. Так как любой интерфейс является потомком IUnknown, то любой интерфейс имеет и метод QueryInterface. Поэтому в общем случае не важно, какой именно интерфейс может использовать клиент. При помощи метода QueryInterface он может получить доступ к любому интерфейсу объекта.

Интерфейс IUnknown обеспечивает работу еще одного важного механизма объекта COM – механизма учета ссылок. Объект должен существовать до тех пор, пока его использует хотя бы один клиент. При этом клиент не может самостоятельно уничтожить объект, ведь с ним могут работать и другие клиенты.

Поэтому при передаче наружу очередного указателя на интерфейс объект увеличивает специальный счетчик ссылок на единицу. Если один клиент передает другому указатель на интерфейс этого объекта, то клиент, получающий указатель, обязан еще раз инкрементировать счетчик ссылок. Для этого используется метод AddRef интерфейса IUnknown.

При завершении работы с интерфейсом клиент обязан вызвать метод Release интерфейса IUnknown. Этот метод уменьшает счетчик ссылок на единицу. После обнуления счетчика объект уничтожает себя.

Сервер

Сервер COM представляет собой исполняемый файл приложения или динамическую библиотеку, который содержит один или несколько объектов одного или разных классов. Различают три типа Сервер.

Внутренний сервер (inprocess server) реализуется динамическими библиотеками, которые подключаются к клиенту и работают в одном адресном пространстве.

Локальный сервер (local server) создается отдельным процессом, который работает на одном компьютере с клиентом.

Удаленный сервер (remote server) создается процессом, который работает на друго компьютере по отношению к клиенту.

Рассмотрим локальный сервер. Получаемый клиентом указатель интерфейса в этом случае ссылается на специальный proxy-объект COM (назовем его заместителем, который функционирует внутри клиентского процесса). Заместитель предоставляет клиенту те же интерфейсы, что и вызываемый объект COM на локальном сервере. Получив вызов от клиента, заместитель упаковывает его параметры и при помощи служб ОС передает вызов в процесс сервера. В локальном сервере вызов передается еще одному специализированному объекту – заглушке (stub), который распаковывает вызов и передает его требуемому объекту COM. Результат вызова возвращается клиенту в обратном порядке.

Рассмотрим удаленный сервер. Он функционирует так же, как и локальный сервер. Однако передача вызовов между двумя компьютерами осуществляется средствами DCOM – с помощью механизма вызова удаленных процедур (Remote Procedure Call, RPC).

Для обеспечения работы локальных и удаленных серверов используется механизм маршалинга и демершалинга. Маршалинг реализует единый в рамках COM формат упаковки параметров запроса, демаршалинг отвечает за распаковку. В описанных выше реализациях серверов за выполнение этих операций отвечают заместитель и заглушка. Эти типы объектов создаются совместно с основным объектом COM. Для этого применяется IDL.

Библиотека COM

Для обеспечения выполнения общих функций и базовых интерфейсов в ОС устанавливается специальная библиотека COM (конкретная реализация может быть различной). Доступ к функциям библиотеки осуществляется стандартным способом, а не через интерфейс.

Согласно спецификации, имена всех библиотечных функций начинаются с приставки «Со».

При установке использующего COM приложения в системный реестр записывается информация обо всех используемых им объектах COM:

Ø   Идентификатор класса (Class Identifier, CLSID), который однозначно определяет класс объекта;

Ø   Тип сервера объекта – внутренний, локальный или удаленный;

Ø   Для локальных и внутренних серверов сохраняется полное имя динамической библиотеки или исполняемого файла;

Ø   Для удаленных серверов записывается полный сетевой адрес.

Предположим, что клиент пытается использовать некоторый объект COM, который до этого момента не использовался.

Следовательно, клиент не может получить указатели на объект и интерфейс. В этом случае он обращается к библиотеке COM и вызывает метод CoCreateInstance, передавая ей в качестве параметра CLSID нужного класса, IID интерфейса и требуемый тип сервера.

Библиотека при помощи диспетчера управления службами (Service Control Manager, SCM) обращается к системному реестру, по идентификатору класса – объект, и возвращает библиотеке указатель на запрошенный интерфейс.

Библиотека COM передает управление клиенту, который в последствии может обращаться непосредственно к объекту. Схема создания первого экземпляра объекта с помощью библиотеки COM и системного реестра приведена на рисунке.


Рис.4. Создание первого экземпляра объекта с помощью библиотеки COM

Для неявной инициализации созданного объекта (установки значений свойств) может использоваться специальный объект самостоятельно, применив специальные интерфейсы (IPersistFile, IPersistStorage, IPersistStream).

Фабрика класса

Для запуска экземпляра класса используется специальный объект –фабрика класса. С его помощью можно создать как один объект, так и несколько его экземпляров. Для каждого класса должна существовать собственная фабрика класса.

Объект COM имеет право называться фабрикой класса, если он поддерживает интерфейс IClassFactory. В нем реализованы всего два метода:

Ø   CoCreateInstance – создает новый экземпляр класса. Все необходимые параметры, кроме IID, метод получает от фабрики класса. В этом его отличие от одноименного общего метода библиотеки.

Ø   LockServer –оставляет сервер функционировать после создания объекта.

Для вызова фабрики класса существует специальный общий метод CoClassObject. В качестве параметра ему передается CLSID нужного класса и IID интерфейса (IClassFactory). Метод ищет требуемую фабрику и возвращает указатель на интерфейс. С его помощью и используя метод CoCreateInstance, клиент заставляет фабрику класса создать объект.

Библиотека типов

Чтобы документировать интерфейсы объекта для пользователей, разработчик создает информацию о типах объекта. Для этого используется язык IDL.

Вся информация объединяется в специальной библиотеке типов. Она может описывать свойства и методы (а также их параметры) интерфейсов и содержать сведения о необходимых заглушках и заместителях. Информация об отдельном интерфейсе оформляется в виде отдельного объекта внутри библиотеки.

Для создания библиотеки типов, описанной при помощи операторов IDL, используются специальные компиляторы. Доступ к библиотеке осуществляется по CLSID класса объекта. Кроме того, библиотека имеет собственный GUID, который сохраняется в системном реестре при регистрации объекта.

Каждая библиотека типов имеет интерфейс ItypeLib, который работает с ней, как с единым объектом. Для доступа к информации об отдельном интерфейсе используется интерфейс ItypeInfo.

Для доступа к библиотеке по GUID используется общий метод LoadRegTypeLib. Если клиенту известно имя файла библиотеки, то можно воспользоваться методом LoadTypeLib.


Информация о работе «Теория проектирования удаленных баз данных»
Раздел: Информатика, программирование
Количество знаков с пробелами: 102741
Количество таблиц: 6
Количество изображений: 12

Похожие работы

Скачать
30483
19
2

... на завершающей проверочной стадии проектирования БД, мы начнем обсуждение вопросов проектирования с рассмотрения причин, которые заставили Кодда создать основы теории нормализации. Универсальное отношение Предположим, что проектирование базы данных "Питание" (рис. 3.2) начинается с выявления атрибутов и подбора данных, образец которых (часть блюд изготовленных и реализованных 1/9/94 г.) показан ...

Скачать
60871
0
7

... позволяют на любом этапе разработки внести изменения в базу данных и модифицировать ее структуру без ущерба для введенных ранее данных. В процессе разработки канонической модели данных предметной области для проектирования реляционной базы данных необходимо выделить информационные объекты (ИО), соответствующие требованиям нормализации данных, и определить связи между ИО с типом отношений один ...

Скачать
36713
2
4

... число разнородных компонентов. В связи с наглядностью представления концептуальных схем баз данных ER-модели получили широкое распространение в системах CASE, поддерживающих автоматизированное проектирование реляционных баз данных. Среди множества разновидностей ER-моделей одна из наиболее развитых применяется в системе CASE фирмы ORACLE. Ее мы и рассмотрим. Более точно, мы сосредоточимся на ...

Скачать
31895
1
2

... аномалии связаны с избыточностью (дублированием) данных в БД. Определить дублирование данных в БД, а значит и предсказать возможность возникновения аномалий обновления можно на этапе проектирования структуры базы данных. Одним из наиболее алгоритмически и понятийно простых методов устранения избыточности хранения данных является метод нормальных форм, который основан на анализе функциональных ...

0 комментариев


Наверх