
- •Государственный комитет рф по высшему образованию
- •0. Введение.
- •0.1. Идея общей интеграции.
- •0.2. Взаимодействие на уровне процедур.
- •0.3. Распределенные объекты.
- •0.4. Почему corba.
- •1. Поддержка на различных платформах.
- •2. Устойчивость стандарта.
- •3. Сложность освоения.
- •4. Поддержка повторного использования кода.
- •1. Постановка задачи.
- •1.1. Классические объекты.
- •1.2. Распределенные объекты в терминах спецификации corba.
- •1.3. Требования, предъявляемые к orb-у.
- •2. СпецификацияCorba.
- •2.1. Объектная модель.
- •2.2. Обзор архитектурыCorba.
- •2.3. Пример Брокеров Объектных Запросов.
- •3. Структура системы.
- •3.1. Уточнение деталей реализации.
- •3.2. Структура ядра системы.
- •3.3. Структура библиотеки.
- •3.4.Структура подсистемы обработки запросов.
- •3.5. Входные и выходные данные.
- •4. Протокол обменаGiop.
- •4.1. Особенности и цели протокола.
- •4.2. Обзор протоколаGiop.
- •4.3. Синтаксис Общего Представления Данных -cdr.
- •4.4. Формат сообщений протокола giop.
- •4.5. Транспорт для протоколаGiop.
- •4.6. Реализация взаимодействия по протоколуGiop.
- •4.7. Поддержка протоколаGiop в рамках отображения дляObject Pascal.
- •5. Разработка отображения для языкаObject Pascal.
- •5.1. Множественное наследование.
- •5.2. Статические экземпляры классов.
- •Initialization
- •Initialization
- •6. Технология написания и отладки приложений, работающих с распределенными объектами.
- •6.1. Этапы разработки программы.
- •6.2. Технология написания сервера объекта.
- •6.3. Технология написания клиента объекта.
- •6.4. Отладочные возможности библиотеки.
- •7. Пример программы, работающей с распределенными объектами.
- •7.1. Последовательность действий при создании объекта.
- •7.2. Объект библиотека.
- •7.3. Сервер объекта.
- •7.3. Клиент объекта.
- •7.4. Окончательный результат.
- •8. Анализ конкурентоспособности программного продукта.
- •8.1. Введение.
- •8.2. Ситуация на рынке.
- •8.3. Программные продукты - конкуренты.
- •8.4. Основные понятия.
- •8.5. Параметры для оценки эффективности.
- •8.6. Расчет эффективности.
- •8.7. Цена.
- •8.8. Конкурентоспособность.
- •8.9. Выводы и прогнозы.
- •9. Вопросы эргономики и их решение для создания комфортных условий труда программистов.
- •9.1. Введение.
- •9.2. Рабочее место программиста.
- •9.3. Вредные факторы, присутствующие на рабочем месте и их классификация.
- •9.4. Вредные производственные воздействия.
- •9.5. Эргономические требования.
- •9.6. Эргономика окружающей среды.
- •9.7. Экологическая безопасность.
- •9.8. Выводы.
4.7. Поддержка протоколаGiop в рамках отображения дляObject Pascal.
При реализации отображения для языка Object Pascal наиболее актуальным было обеспечение возможности быстрого и удобного кодирования данных, потому что вызов изDLL написанных наC функций не обеспечивал ни первого, ни второго. В языкеC++ весьма удобным механизмом является использование стандартных потоков с перегруженными операциями<< и>>. В качестве результата хотелось бы иметь нечто аналогичное. В итоге получилось следующее.
Имеющиеся в Delphi стандартные классы потоком, наследников отTStream позволяют производить только чтение и запись абстрактного буфера данных. Было принято решение не изменять имеющееся определение классаTStream, а вместо этого определить классTStreamable, у которого помимо всего прочего будет поле - типаTStream, что даст возможность осуществлять чтение и запись у любого потока.
Сначала был определен набор методов для чтение/записи базовых типов. В качестве примера можно привести методы для чтения и записи типаLong (являющегося аналогом типаCardinal вObject Pascal):
procedureTStreamable.WriteLong(L: Long);
begin
Align4;
Stream.Write(L, 4);
end;
functionTStreamable.ReadLong: Long;
begin
Align4;
Stream.Read(Result7, 4);
end;
Метод Align4 производит выравнивание границы начала записи числа на позицию, кратную 4, как того требует спецификацияCDR. Например, чтобы поместить в поток два числа2и8, а также строку‘Hello’нужно было написать примерно следующий код:
S.WriteLong(2);
S.WriteLong(8);
S.WriteString(‘Hello’);
После некоторых опытов пришла идея сделать все методы чтения/записи функцией с одним параметров - значением или переменной соответствующего типа, которая будет возвращать ссылку на тот же самый объект типаTStreamable, у которого она определена. Тогда было введено еще два набора функций, которые были реализованы следующим образом:
functionTStreamable.PutLong(L: Long): TStreamable;
begin
Align4;
Stream.Write(L, 4);
Result := Self;
end;
function TStreamable.GetLong(var L: Long): TStreamable;
begin
Align4;
Stream.Read(Result, 4);
Result := Self;
end;
Перевызов соответствующих методов WriteLong иReadLong уменьшил бы эффективность полученного кода (за счет дополнительного присваивания) и поэтому код просто дублировался. В результате на первый взгляд небольшой потери в эффективности появилась возможность написания выражений в гораздо более красивом и удобном8стиле. Приведенный выше пример мог теперь быть записан следующим образом:
S.PutLong(2).PutLong(8).PutString(‘Hello’);
Соответственно чтение из потока стало выглядеть так:
var
L1, L2: Long;
Msg: string;
...
S.GetLong(L1).GetLong(L2).GetString(Msg);
Более того, была проведена оптимизация создаваемого кода, посредством реализации данным методов на встроенном ассемблере. В соответствии с моделью вызовов register, которая по умолчанию принята компиляторомDelphi, первый параметр функции (указатель на объект) передается в регистреEAX, а результат функции, если он помещается тоже возвращается в регистреEAX. Соответственно при реализации данных методов на языке ассемблера нужно всего лишь на протяжении выполнения всего метода сохранить переданное в самом начале значение. Кроме того, можно сэкономить на формировании фрейма стека. В итоге были получены следующие результаты. Ассемблерный код для методаWriteLong, сгенерированный компилятором, который можно получить в отладчикеTurbo Debugger for Win32 содержит 19 команд ассемблера и выполняется по приблизительным оценкам за 21 такт процессораIntel Pentium. Код для методаPutLong, написанный на ассемблере, содержит 15 команд ассемблера и выполняется за 17 тактов процессораIntel Pentium. Листинг обоих методов приведен в приложении Б. При оценке количества тактов не учитывалась возможность процессораIntel Pentium параллельного выполнения нескольких команд и использовались данные, представленные в литературе [4].
В итоге был получен более производительный и более удобный в использовании код. В плане оптимизации несколько методов были также переписаны на языке ассемблера. Но после анализа алгоритма выяснилось, что потенциально большое время занимает выполнение метода Write у потоков. Поэтому в будущем планируется написание специализированного класса, специально оптимизированного под кодирование/декодирование данных в соответствии сCDR.