Рефераты

Протоколы и стандарты объектно-ориентированного программирования

Протоколы и стандарты объектно-ориентированного программирования

OLE

DDE

Clipboard

РЕФЕРАТ

по дисциплине "Теория проектирования трансляторов"

на тему Протоколы и стандарты объектно-ориентированного программирования

Выполнен студентом группы АП-1-91 Маслюковым А.О.

СОДЕРЖАНИЕ

Предисловие

MS Windows и новый метод разработки программ

Динамический обмен данными

OLE-технология

Заключение

Список литературы

Приложение 1.Пример использования OLE-технологии

Предисловие

Наиболее распространенным языком программирования последне-

го десятилетия безусловно является С. Этому способствовали такие

его особенности, как лаконичность, мощность, гибкость, мо-

бильность. Вместе с тем, стремительное усложнение приложений, для

реализации которых применяются традиционные процедурно-ориентиро-

ваннные языки программирования и, в частности С, заставляют гово-

рить об определенном кризисе в их использовании, связанном преж-

де всего с недостаточной надежностью и выразительной способностью.

Подобных недостатков во многом лишены языки объектно-ориен-

тированнго программирования (ООП), в сонове которыхлежит идея мо-

делирования объектов посредством иерархически связанных классов.

Отдельно взятый класс рассматривается как совакупность множества

данных и операций над ними, причем доступ к элементам данных

класса возможен только посредством операций этого класса. Уста-

новление четкой взаимозависимости между данными и операциями ве-

дет к большой целостности данных и значительно повышает надеж-

ность программ по сравнению с традиционными языками программиро-

вания. Кроме того, идея программирования с помощью классов во

многом использует тот же подход, который позволяет людям формиро-

вать модели объектов реального мира.

Впервые идеи ООП были реализованы в середине 60-х годов в

языке программирования Симула-67. Последний, однако, не нашел в

то время широкого распространения как в силу своей относительно

меньшей производительности по сравнению с традиционными языками

типа FORTRAN, ALGOL, PL/1 так и, возможно, неадекватности предла-

гаемых средств решаемым в то время задачи. Еще одним важным огра-

ничением для распространеия Симулы-67 стали трудности, с которы-

ми пришлось столкнуться большинству программистов при его изуче-

нии. Дело в том, что наряду с целым рядом безусловных достоинств,

идеи ООП обладают и одним существенным недостатком - они далеко

не просты для понимания и особенно для освоения с целью практи-

ческого использования.

С++ - развитие С.

С++ - это объектно-ориентированыый язык, то есть язык, поз-

воляющий программисту оперировать объектами некоторых типов,

предварительно им определенным. Название языка "С++" отражает

эволюционный характер изменения языка С (запись "++", в языке С,

означает, что к какой-то переменной прибавляется единица). Он

имеет еще более мощные и гибкие средства для написания эффектив-

ных программ, чем С, от которого он произошел. Человек, програм-

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

тех возможностей, которые предоставляет С++.

Но не менее важным является то, что такой распространенный и

универсальный язык, как С, сохранен в качестве основы. С прост,

эффективен, переносим. Чего только нет в языке С: строковых дан-

ныхнет, матриц нет, средств параллельного программирования тоже

нет. Нет даже ввода-вывода.

Типы, операции и операторы С очень близки к тому, с чем мы

имеем дело в Ассемблере,- числа, адреса, арифметические и логи-

ческие действия, циклы... Кроме того, многие особенности С нед-

вусмысленно намекаю компилятору, как сократить код и время испол-

нения программы. Эти характерные черты языка С позволяют напи-

сать эффективно работающий и не слишком сложный компилятор. И хо-

тя в машинных кодах на разных компьютерах элементарные операции

обозначаютс по-разному, вряд ли разработчику компилятора придет в

голову интерпретировать простейшие выражения каким-нибудь ориги-

нальным способом. Именно поэтому язык С "идет везде и на всем",

программы, написанные на нем, работают эффективно, и их можно пе-

реносить с одного компьютера на другой.

Большинство языков программирования созданы для решения оп-

ределенного круга задач. В них не только не хватает определенных

типов данных и функций, но и много лишнего с точки зрения челове-

ка, далекого от области, на которую ориентирован язык. Специали-

зированные типы данных или операторы, требующие нетривиальной

поддержки, затрудняют изучение языка и мешают вашей работе, если

вы ими не собираетесь пользоваться. Поэтому С, в котором нет ни-

чего лишнего, популярен среди широкого круга программистов. Соот-

ветствующие библиотеки могут добавить к средствам языка специали-

зированные функции для работы со строками, файлами, списками, ус-

тройствами ввода-вывода, математическими объектами и т.д. Остает-

ся только выбрать то, что нужно лично вам. Заголовочные файлы об-

легчают использование библиотек, предоставляют полезные типы дан-

ных, глобальные переменные, макроопределения... Они во многом ус-

траняют противоречие между эффективностью программы и удобством

использования библиотечных функций. Они также позволяют не повто-

рятся и не писать по нескольку раз одно и тоже в различных прог-

раммах. Поскольку С был создан специально для системного програм-

мирования, он имеет возможности низкого уровня, позволяющие "иг-

рать без правил". В зависимости от устройства и операционной сис-

темы вашей машины вы можете "влезть" в видеопамять или использо-

вать системные программы, находящиеся в оперативной памяти.

В любом случае вы можете рассматривать код собственной прог-

раммы как данные, а массив данных как код функции, квадратную

матрицу как вектор, а текст как бинарное дерево. Что бы ни нахо-

дилось в памяти - это всего лишь последовательная цепочка чисел.

Если вы не боитесь риска - можете делать все, что вам вздумается.

Современные прграммисты выбирают С не только из-за его преи-

муществ. В настоящее время мы имеем дело с цепной реакцией: чем

больше написано на С, тем больше на нем напишут еще. Это одна из

причин, почему язык С++ сохраняет С в качестве подмножества.

По мнению автора С++, Бьерна Страуструпа, различие между

идеологией С и С++ заключается примерно в следующем: программ на

С отражает "способ мышления" процессора, а С++ - способ мышления

программиста. Отвечая требованиям современного программирования,

С++ делает акцент на разработке новых типов данных, наиболее пол-

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

приложения. На С пишут библиотеки функций, С++ позволяет созда-

вать библиотеки классов. Класс является ключевым понятием С++.

Описание класса содержит описание данных, требующихся для пред-

ставления объектов этого типа, и набор операций для работы с по-

добными объектами.

В отличие от традиционных структур С или Паскаля, членами

класса являются не только данные, но и функции. Функции-члены

класса имеют привилегированный доступ к данным внутри объектов

этого класса и обеспечивают интерфейс между этими объектами и ос-

тальной программой. При дальнейшей работе совершенно не обяза-

тельно помнить о внутренней структуре класса и мехагизме работы

"встроенных функций". В этом смысле класс подобен электрическому

прибору - мало кто знает о его устройстве, но все знают, как им

пользоваться.

Часто в целях повышения эффективности и упрощения структуры

программы приходится заставлять ее работать с разнородными объек-

тами так, как если бы они имели один и тотже тип. Например, ок-

ружность и квадрат естественно рассматривать как варианты геомет-

рической фигуры. Полезно составлять списки фигур, нарисованных на

экране, или функций, которые их размножают, двигают и т.д. О точ-

ном типе объекта приходится порой забывать. Список геометричес-

ких фигур "не знает", что в нем находится - отрезки или звездоч-

ки. Не знает этого и компилятор. Но все время, пока вы рисуете

эти объекты, неизбежно приходится "помнить", что они из себя

представляют. Конечно, возможности низкого уровня позволяют "за-

бывать" и "вспоминать" когда и как нам заблагорассудится, но при

этом компилятор теряет контроль над осмысленностью действий.

Использование производных классов и виртуальных функций поз-

воляет избежать рискованной техники и не заботится о том, в ка-

кой форме объект типа "геометрическая фигура" хранит информацию о

том, круг он или квадрат. (Кроме возможностей ООП, создание ти-

пов данных "треугольник" или "квадрат" как производные от базово-

го класса "геометрическая фигура" отражает логическую связь поня-

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

можно делать с объектом, а не то, как это делать. Создавая класс

"геометрическая фигура", мы можем включить в него виртуальные

функции рисования, увеличения, поворота. С использованием этих

функций можно создать еще один член класса.

Затем можно разработать библиотеку программ интерактивной

графики, снабдив ее средствами диалого, функциями вроде дополне-

ния некоторой области экрана одинаковыми геометрическими фигура-

ми и т.д. Библиотечные функции будут вызывать функции-члены клас-

са "геометрическая фигура": рисования, движения, поворота,увели-

чения. А после того, как мы все это напишем, откомпилируем, спря-

чем текст функций, которые считаем своей интеллектуальной соб-

ственностью, начинается самое интересное. Теперь мы можем опи-

сать сколько угодно новых типов фигур - многоугольников, звездо-

чек, эллипсов - производных от класса "геометрическая фигура" и

объяснить, как их рисовать, увеличивать и поворачивать. Как дви-

гать - объяснять не надо. Это уже есть в базовом классе. Функции

нашей библиотеки могут работать собъектами вновь созданных типов,

для них это варианты геометричесой фигуры. Следует отметить, что

в производных классах могут (и, как правило, должны) появлятся

данные и функции, которых нет в базовом классе. Однако ни одна из

функций, обрабатывающих "геометрические фигуры", никогда не уз-

нает о специфических свойствах многоугольника или эллипса, кроме

того, что они по-своему рисуются, увеличиваются и поворачиваются.

Производный класс сам может быть базовым для других классов, а

поздние версии С++ позволяют сделать один класс производным от

нескольких других.

При написании программы часто допускаются досадные оплошнос-

ти, обнаруживающиеся только на стадии выполнения и, увы, слишком

поздно. Например, если переменная по смыслу - знаменатель дроби,

хотелось бы получить сообщение об ошиюке тогда, когда ей присваи-

вается ноль, а не тогда, когда на этот ноль что-нибудь делится.

Или, скажем, функция рисования точки. Невозможно удержаться от

соблазна вызвать ее хотя бы раз без проверки выхода за границы

экрана. В то же время , если мы пишем программу рисования линии,

обязательно нужна функция, которая тупо ставит точку - и как мож-

но быстрее. Существует много ситуаций, когда функции и данные

следует разрешить использовать только привилегированным функциям,

над которыми ва "хорошо подумали". В С++ этого можно добиться,

сделав "опасные" данные и функции защищенными членами какого-ни-

будь класса. К ним имеют доступ только функции-члены этого же

класса, а так же друзья класса. Напротив, если данные или фун-

кции-члены объявлены public, они являются общедоступными.

С++ предоставляет в распоряжение программиста сложные типы

данных. Однако ни аппарат классов, ни перегрузка операций не

влияют на эффективность. То, что класс - это класс, известно

только компилятору. Если функции-члены классов объявлены inline,

на их вызов не требуется время. Фактически это не функции, а под-

становки. Лишь виртуальные функции оставляют относительно не-

большой след в оперативной памяти.

Из всего выше сказанного вытекает логичный вывод: С++ наибо-

лее удобный, универсальный и необходимый язык. Но все же возни-

кает вопрос, что же было написано на этом языке, используя прин-

ципы ООП, что можно было бы "потрогать" любому программисту или

пользователю. Ответ очевиден - это Microsoft Windows.

MS Windows и новый метод разработки программ.

Одним из наиболее важных механизмов взаимодействия программ

является обмен данными. В MS Windows существует несколько способов

взаимодействия приложений:

- почтовый ящик;

- динамический обмен данными;

- встраивание объектов.

Специальный почтовый ящик (clipboard) Windows позволяет

пользователю переносить информацию из одного приложения в другое,

не заботясь об ее форматах и представлении.

В отличие от профессиональных операциональных операционных

систем, где механизм обмена данными между программами доступен

только программисту, в Windows это делается очень просто и наг-

лядно для пользователя.

Механизм обмена данных между приложениями - жизненно важное

свойство многозадачной среды. И в настоящее время производители

программного обеспечения пришли уже к выводу, что для переноса

данных из одного приложения в другое почтового ящика уже недоста-

точно. Появился новый, более универсальный механизм - OLE (

Object Linking and Embedding )

- Встроенная объектная связь, который позволяет пе-

реносить из одного приложения в другое разнородные данные. Напри-

мер, с помощью этого механизма данные, подготовленные в системе

сетевого планирования Time Line for Windows ( Symantec ), можно

переносить в текстовый процессор Just Write ( Symantec ), а за-

тем, скажем, в генератор приложений Object Vision (Borland).

Правда, это уже нестандартное средство Microsoft Windows, но тем

не менее реализация OLE стала возможной именно в Windows.

Кроме механизма почтового ящика, предназначенного, в основ-

ном, для пользователя, программисту в Windows доступны спе-

циальные средства обмена данными между приложениями.

Программным путем можно установить прямую связь между зада-

чами, например, принимая данные из последовательного порта, авто-

матически помещать их, скажем, в ячейки электронной таблицы

Excel, средствами которой можно тут же отображать сложные зависи-

мости в виде графиков или осуществлять их обработку в реальном

режиме времени (этот механизм носит название динамического обме-

на данными - Dynamic Data Exchange, DDE ).

Основные термины

Клиентское приложение DDE - приложение, которому необходи-

мо установить диалог с сервером и получить данные от сервера в

процессе диалога.

DDE-диалог - взаимосвязь между клиентским и серверным при-

ложениями.

Сервер-приложение - DDE приложение, которое передает дан-

ные клиенту в процессе диалога.

DDE-Транзакция -обмен сообщениями или данными между клиен-

том и сервером.

Item имя - строка, идентифицирующая некоторое множество

данных, которое сервер в состоянии передать клиенту в процессе

диалога.

Service имя - строка, генерируемая сервером и используе-

мая клиентом для установления диалога.

Строковый указатель - двойное слово, генерируемое опера-

ционной системой, идентифицирующее строку, передающуюся в процес-

се динамического обмена данными.

Topic имя - строка, которая идентифицирует тип данных,

необходимых клиентскому приложению при динамическом обмене данных.

Фильтр транзакции - флаг, который препятствует передаче

нежелательных типов транзакций в функцию обратного вызова.

В Microsoft Windows динамический обмен данных является фор-

мой связи, которая использует общие области памяти для обмена

данными между приложениями. Приложение может использовать DDE в

некоторый момент времени для передачи и получения новых данных от

сервера.

Механизм DDE схож с механизмом почтового ящика, который яв-

ляется частью операционной системы WINDOWS. Существует лишь нез-

начительная разница в том, что почтовый ящик, в большинстве слу-

чае, используется как буфер временного хранения информации. DDE

может быть инициализирован пользователем и в большинстве случаев

продолжать работать без его вмешательства.

Библиотека DDEML обеспечивает пользователя набором средств,

которые упрощают использование механизма DDE в WINDOWS приложе-

ниях. Вместо того, чтобы обрабатывать, получать и передавать DDE

сообщения напрямую, приложения используют функции DDEML библиоте-

ки. Библиотека DDEML также обеспечивает работу со строками и раз-

деляемыми данными, генерируемыми DDE приложениями. Вместо того,

чтобы использовать указатели на общие области памяти, DDE прило-

жения создают и обмениваются строковыми указателями, которые

идентифицируют строки и данные.

Уже существующие приложения, использующие протокол DDE, ос-

нованный на сообщениях полностью совместимы с теми, которые ис-

пользуют библиотеку DDEML. Вот почему приложение, использующее

DDE-протокол могут установить диалог и выполнять транзакции с

приложениями, использующими библиотеку DDEML.

Взаимосвязь между клиентом и сервером.

DDE возникает всегда между клиентским приложением и сервер-

ным. Клиентское приложение инициализирует обмен данными путем ус-

тановления диалога с сервером и передачи транзакции. Транзакция

необходима для данных и обслуживания. Сервер отвечает на транзак-

цию и обеспечивает клиента данными. Сервер может иметь сразу нес-

колько клиентов в одно и тоже время, в свою очередь, клиент мо-

жет получать данные сразу от нескольких серверов. Некоторое при-

ложение одновременно может быть и клиентом и сервером. В добавок

к вышесказанному, клиент и сервер могут оборвать диалог в любое

удобное для них время.

DDE сервер использует три зарезервированных типа имен, рас-

положенных иерархично: service, topic item - уникально идентифи-

цируют некоторое множество данных, которое сервер может передать

клиенту в процессе диалога.

Service имя - это строка, которую генерирует сервер в те

промежутки времени, в которые клиент может установить диалог с

сервером.

Topic имя - это строка, которая идентифицирует логичес-

кий контекст данных. Для сервера, который манипулирует файлами,

topic имена это просто названия файлов; для других серверов - это

специфические имена конкретного приложения. Клиент обязательно

должен указывать topic имя вместе с service именем, когда он хо-

чет установить диалог с сервером.

Item имя - это строка, которая идентифицирует некото-

рое множество данных, которое сервер может передать клиенту в

процессе транзакции. Например, item имя может идентифицировать

ЦЕЛОЕ ( int, integer ), СТРОКУ ( string, char * ), несколько па-

раграфов текста, или BITMAP образ.

Все вышеуказанные имена позволяют клиенту установить диа-

лог с сервером и получить от него данные.

Системный режим

Системный режим работы обеспечивает клиента всей необходи-

мой информцией о сервере.

Для того, чтобы определить, какие серверы доступны в дан-

ный момент времени, а также какой информацией они могут обеспе-

чить клиента, последний, находясь в начальном режиме работы, дол-

жен установить имя устройства, равное NULL. Такой шаблон диалога

максимально увеличивает эффективность работы, а также работу с

сервером в системном режиме. Сервер, в свою очередь, должен под-

держивать нижеописанные item имена, а также другие, часто ис-

пользуемые клиентом:

SZDDESYS ITEM TOPICS - список item имен, с которыми может

работать сервер в данный момент времени. Этот список может изме-

няться время от времени.

SZDDESYS ITEM SYSITEMS - список item имен, с которыми мо-

жет работать сервер в системном режиме.

SZDDDESYS ITEM STATUS - запросить текущий статус сервера.

Обычно, данный запрос поддерживается только в формате CF_TEXT и

содержит строку типа Готов/Занят.

SZDDE ITEM ITEMLIST - список item имен, поддерживаемых сер-

вером в несистемном режиме работы. Этот список может меняться

время от времени.

SZDDESYS ITEM FORMATS - список строк, представляющий собой

список всех форматов почтового ящика, поддерживаемых сервером в

данном диалоге. Например, CF_TEXT формат представлен строкой TEXT.

Основное назначение и работа функции обратного вызова

Приложение, которое использует DDEML, должно содержать фун-

кцию обратного вызова, которая обрабатывает события, полученные

приложением. DDEML уведомляет приложение о таких событиях путем

посылки транзакций в функцию обратного вызова данного приложения.

В зависимости от флага фильтра транзакции, сформированного

при вызове функции DdeInitialize, функция обратного вызова полу-

чает отсортированные транзакции вне зависимости от того, являет-

ся ли данное приложение клиентом, сервером или тем и другим од-

новременно. Следующий пример демонстрирует наиболее типичное ис-

пользование функции обратного вызова.

HDDEDATA CALLBACK DdeCallback( uType, uFmt, hconv, hsz1,

hsz2, hdata, dwData1, dwData2 )

UINT uType; // Тип транзакции

UINT uFmt; // Формат почтого ящика

HCONV hconv; // Идентификатор диалога

HSZ hsz1; // Идентификатор строки #1

HSZ hsz2; // Идентификатор строки #2

HDDEDATA hdata; // Идентификатор глобального объек-

та памяти

DWORD dwData1; // Данные текущей транзакции #1

DWORD dwData2; // Данные текущей транзакции #2

{

switch (uType)

{

case XTYP_REGISTER:

case XTYP_UNREGISTER:

. . .

return (HDDEDATA) NULL;

case XTYP_ADVDATA:

. . .

return (HDDEDATA) DDE_FACK;

case XTYP_XACT_COMPLETE:

. . .

return (HDDEDATA) NULL;

case XTYP_DISCONNECT:

. . .

return (HDDEDATA) NULL;

default:

return (HDDEDATA) NULL;

}

}

Параметр uType идентифицирует тип посланной транзакции в

функцию обратного вызова при помощи DDEML. Значения оставшихся

параметров зависят от типов транзакции. Типы транзакций будут об-

суждены нами в разделе "Обработка Транзакций".

Диалог между приложениями

Диалог между клиентом и сервером всегда устанавливается по

требованию клиента. Когда диалог установлен, оба партнера полу-

чают идентификатор, который описывает данный диалог.

Партнеры используют этот идентификатор в большинстве фун-

кций DDEML для посылки транзакций и для их обработки. Клиенту мо-

жет потребоваться диалог как с одним сервером, так и с нескольки-

ми.

Рассмотрим подробно как приложение устанавливает диалог и

получает информацию о уже существующих каналах связи.

Простой Диалог

Клиентское приложение устанавливает простой диалог с серве-

ром путем вызова функции DdeConnect и определяет идентификаторы

строк, которые содержат всю необходимую информацию о service име-

ни текущего сервера и интересущем клиента в данный момент topic

имени.

DDEML отвечает на вызов этой функции посылкой соответствую-

щей транзакции XTYP_CONNECT в функцию обратного вызова каждого

доступного в данный момент времени сервера, зарегистрированное

имя которого совпадает с именем, переданным при помощи функции

DdeConnect при условии, что сервер не отключал фильтр service

имени вызовом функции DdeServiceName.

Сервер может также установить фильтр на XTYP_CONNECT тран-

закцию заданием соответствующего флага CBF_FAIL_CONNECTIONS при

вызове функции DdeInitialize.

В процессе обработки транзакции типа XTYP_CONNECT DDEML пе-

редает полученные от клиента service и topic имена серверу. Сер-

вер должен проверить эти имена и возвратить TRUE, если он в сос-

тоянии работать с такими именами, и FALSE в противном случае.

Если ни один из существующих серверов не отвечает на CONNECT-зап-

рос клиента, функция DDeConnect возвращает ему NULL с информа-

цией о том, что в данный момент времени НЕ возможно установить

диалог.

Однако, если сервер возвратил TRUE, то диалог был успешно

установлен и клиент получает идентификатор диалога

- двойное слово, посредством которого и ведется

обмен данными с сервером.

Затем сервер получает транзакцию вида XTYP_CONNECT_CONFIRM

(в случае, если он НЕ описывал флаг фильтра CBF_FAIL_CONFIRMS при

вызове соответствующей функции).

В нижеприведенном примере производится попытка установить

диалог с сервером, который в состоянии работать с service именем

'My Server' в системном режиме. Считаем, что параметры

hszSysTopic и hszServName уже предварительно созданы нами ранее.

HCONV hConv;

HWND hwndParent;

HSZ hszServName;

HSZ hszSysTopic;

. . .

hConv = DdeConnect(

idInst, // Копия приложения

hszServName, // Идентификатор

service-имени

handle hszSysTopic,// Идентификатор

system-topic-имени

(PCONVCONTEXT) NULL); // Используем контекст

по умолчанию

if( hConv == NULL )

{

MessageBox( hwndParent, "MyServer НЕ доступен!",

(LPSTR) NULL, MB_OK );

return FALSE;

}

. . .

В этом примере функция DdeConnect заставляет DDEML посы-

лать транзакцию вида XTYP_CONNECT в функцию обратного вызова сер-

вера MyServer.

А теперь приведем пример функции обратного вызова сервера,

который обрабатывает транзакцию XTYP_CONNECT и сравнивает свое

зарегистрированное имя с именем, полученным от клиента. Как уже

было отмечено ранее, если они совпадают, то сервер в состоянии

установить диалог с клиентом.

#define CTOPICS 5

HSZ hsz1; // Идентификатор строки,

полученный от DDEML.

HSZ ahszTopics[CT