Главная страница
Навигация по странице:

  • IMyObject и IMyObject 2

  • CoClass

  • Querylnterface

  • Editl и Edit 2. Для взаимодействия .

  • COM объекты. ЛБ 1_Com. Лабораторная работа 1 часть 1 взаимодействие с унаследованным программным кодом 1 реализация внутреннего сервера com в delphi 2


    Скачать 0.79 Mb.
    НазваниеЛабораторная работа 1 часть 1 взаимодействие с унаследованным программным кодом 1 реализация внутреннего сервера com в delphi 2
    АнкорCOM объекты
    Дата28.05.2022
    Размер0.79 Mb.
    Формат файлаdoc
    Имя файлаЛБ 1_Com.doc
    ТипЛабораторная работа
    #554589
    страница1 из 13
      1   2   3   4   5   6   7   8   9   ...   13

    ТРПО


    ТРПО 1

    ЛАБОРАТОРНАЯ РАБОТА №1 часть 1. 1

    ВЗАИМОДЕЙСТВИЕ С УНАСЛЕДОВАННЫМ ПРОГРАММНЫМ КОДОМ 1

    1.1. РЕАЛИЗАЦИЯ ВНУТРЕННЕГО СЕРВЕРА COM В DELPHI 2

    1.2. ЗАДАНИЯ К ЛАБОРАТОРНОЙ РАБОТЕ 12

    ЛАБОРАТОРНАЯ РАБОТА №1 часть 2. 12

    РАЗРАБОТКА и ИСПОЛЬЗОВАНИЕ ActiveX ФОРМ 12

    2.1. ПРИМЕР СОЗДАНИЯ КОМПОНЕНТА ActiveX В СРЕДЕ DELPHI 12

    2.2. ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ 17

    2.3. ОПИСАНИЕ МЕТОДОВ ШИФРОВАНИЯ 18

    Шифр перестановки «Скитала» 18

    Шифрующие таблицы 18

    Применение магических квадратов 20

    ШИФРЫ ПРОСТОЙ ЗАМЕНЫ 20

    Полибианский квадрат 20

    Система шифрования Цезаря 21

    Аффинная система подстановок Цезаря 21

    Система Цезаря с ключевым словом 22

    Шифрующие таблицы Трисемуса 23

    Биграммный шифр Плейфейра 23

    Система омофонов 24

    ШИФРЫ СЛОЖНОЙ ЗАМЕНЫ 25

    Шифр Гронсфельда 26

    Система шифрования Вижинера 26

    Шифр "двойной квадрат" Уитстона 27

    Роторные машины 28

    ШИФРОВАНИЕ МЕТОДОМ ГАММИРОВАНИЯ 31

    ЛАБОРАТОРНАЯ РАБОТА №1 часть 1.

    ВЗАИМОДЕЙСТВИЕ С УНАСЛЕДОВАННЫМ ПРОГРАММНЫМ КОДОМ


    Очень часто сборки .NET должны успешно взаимодействовать со сложными приложениями, где значительную часть кода составляют классические СОМ- серверы. Код модулей СОМ является двоичным и платформенно-зависимым (в отличие от полностью платформенно-независимого кода IL). СОМ-серверы работают с уникальным набором типов данных (BSTR, VARIANT и т. п.), содержание которых
    в разных языках программирования сильно различается. В каждом программном модуле СОМ должны быть реализованы достаточно сложные элементы (такие как фабрики классов, код IDL, записи в реестр). В СОМ-объектах необходимо отслеживать каждую ссылку на объект.

    Eсли ошибиться в ссылках на объект, то это может привести к утечке памяти.

    Следовательно, между типами .NET и СОМ так мало общего, что трудно пред­ставить, как такие разные типы могут успешно взаимодействовать друг с другом. Но в реальной работе возникает очень много ситуаций, когда не­обходимо обеспечить такое взаимодействие. Платформа .NET поддерживает сле­дующие виды совместимости с унаследованным кодом:

    1. вызовы из типов .NET напрямую к модулям DLL, созданным на С (то есть обращения к Win32 API или пользовательским модулям DLL);

    2. взаимодействие .NET и СОМ;

    3. применение элементов управления ActiveX в Windows Forms;

    4. вызовы из типов СОМ к типам .NET;

    В данной лабораторной работе будут рассмотрены пункты 2 и 3.

    1.1. РЕАЛИЗАЦИЯ ВНУТРЕННЕГО СЕРВЕРА COM В DELPHI





    1. Для создания в Delphi внутреннего сервера СОМ, реализуемого библиотекой DLL, выполните команду File New | Other и на странице ActiveX Депозитария выбе­рите пиктограмму ActiveX Library. Будет создан новый проект, который сохраните под каким-то именем, например, PMyComServ.

    Взгляните на созданный Delphi код этого проекта:

    library PMyComServ;

    uses

    ComServ;

    exports

    DllGetClassObject,

    DllCanUnloadNow,

    DllRegisterServer,

    DllUnregisterServer;
    ($R *.RES)

    begin

    end. .

    Оператор uses подключает к проекту модуль ComServ, в котором описан класс TComServ, реализующий свойства сервера СОМ. Объект ComServ этого класса ав­томатически создается в проекте и позволяет через свои свойства получать инфор­мацию о сервере и его объектах.

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


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

    Выполните опять команду File New | Other и на странице ActiveX Депозитария выберите пиктограмму COM Object. Откроется окно (рис.1). В окне Class Name вы должны ука­зать имя класса создаваемого объекта. К этому имени будет автоматически добав­лен префикс «Т». Так что имя «MyObject», которое вы видите на рисунке 1, приве­дет к созданию класса TMyObject.


    Рисунок 1 – Добавление объекта

    Выпадающий список Instancing позволяет выбрать способ создания объекта (см. таблицу 1).

    Таблица 1 Описание способов создания объектов

    Internal

    Объект создается только внутренне

    Single Instance

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

    Multiple Instances

    Для каждого клиента создается отдельный экземпляр объек­та в пределах адресного пространства одного сервера

    В данном примере выбор в списке Instancing не имеет значения, так как для внутреннего сервера, который мы создаем, этот параметр игнорируется.

    Выпадающий список Threading model определяет способы вызова клиентами интерфейса объекта СОМ в многопоточных приложениях (см. таблицу 2).

    Таблица 2 Способы вызова клиентами интерфейса объекта СОМ в многопоточных приложениях

    Single

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

    Apartment

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

    Free

    Объекты обрабатывают вызовы произвольного числа потоков одно­временно. Надо принимать меры для защиты всех локальных и гло­бальных данных

    Both

    To же, что Free, только откаты осуществляются гарантированно в том же потоке

    Neutral

    Множество клиентов могут вызывать объект в различных потоках, но предполагается, что между этими вызовами не возникает конфликтов. Эта модель не может использоваться для объектов, имеющих пользо­вательский интерфейс, т.е. визуальные компоненты. Модель поддер­живается только для СОМ+. Для СОМ она эквивалентна Apartment




    1. В окне Implemented interfaces задается имя интерфейса вашего объекта СОМ по умолчанию. Вы можете согласиться с предложенным именем, которое является именем класса с префиксом «I», или написать новое имя. Созданный интерфейс будет наследником IUnknown и в дальнейшем вы сможете задать его реализацию, пользуясь описанным далее редактором библиотеки типов.

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


    1. Окно Description дает возможность ввести текстовое описание объекта СОМ. Ин­дикатор Include Type Library определяет автоматическую генерацию библиотеки ти­пов. Индикатор Mark interface OleAutornation разрешает маршаллинг — вызов функции интерфейса удаленными объектами в другом процессе и на другой машине, чтобы не усложнять свою задачу, выключите этот индикатор.

    После того, как вы заполните всю информацию в окне и щелкнете на ОК перед вами откроется окно редактора библиотеки типов (рисунок 2), а в окне Редактора Кода вы сможете увидеть заготовку модуля объекта СОМ. Она будет иметь вид:

    unit UObject;

    {$WARN SYMBOL_PLATFORM OFF}

    interface
    uses

    Windows, ActiveX, Classes, ComObj, PMyComServ_TLB, StdVcl;

    type

    TMyObjec=class (TTypedComObject, IMyObject)

    protected

    // Здесь объявляютсяметодыинтерфейса

    end;
    implementation

    uses ComServ;

    initialization

    TTypedComObjectFactory.Create(ComServer, TMyObject,

    Class_MyObject, ciMultilnstance, tmApartment);

    end.

    1. Вы видите, что в раздел initialization включен конструктор фабрики класса. Класс фабрики класса создан Delphi автоматически.

    2. Вызвав Менеджер Проектов (команда View Project Manager) вы увидите, что по­мимо этого модуля сгенерировался и включился в проект файл РМуComServ_TLB.pas — модуль библиотеки типов.

    3. Разработка методов созданного объекта. В первый момент после создания объекта окно редактора библиотеки типов (рис. 2) откроется ав­томатически. В дальнейшем вы в любой момент можете вызвать это окно коман­дой View | Type Library. Эта команда доступна только в том случае, если ваш проект содержит библиотеку типов.




    Рисунок 2 - Редактор библиотеки типов


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

    2. Начнем с добавления методов в интерфейс IMyObject. Выделите в левой панели вершину этого интерфейса и щелкните на быстрой кнопке New Method. В дереве левой панели появится вершина нового метода. Назовите этот метод Add — он будет складывать два числа. Выделите вершину метода и пе­рейдите в правой панели на страницу Parameters, которая показана на рисунке 3. В выпадающем списке Return Type надо выбрать тип возвращаемого методом значения - в нашем примере float. Для з
      адания параметров метода нажмите кнопку Add.

    Рисунок 3 - Определение входных и выходных параметров

    1. В нижнем окне панели появится строка, соответствующая вводимому пара­метру. В столбце Name надо задать имя параметра («Numberl» на рисунке 3). В столбце Туре надо выбрать из выпадающего списка тип параметра. В столбце Mo­difier можно выбрать модификаторы параметра: входной, выходной, необязатель­ный, со значением по умолчанию и т.п. В нашем примере можно оставить значе­ние по умолчанию «[in]».

    2. Аналогичным образом надо задать второй параметр. Далее так же, как вы до­бавили метод Add, добавьте в интерфейс метод Sub — вычитание чисел.

    3. Теперь надо ввести в объект второй интерфейс. Щелкните на быстрой кнопке New Interface (крайняя левая). В левой панели появится новая вершина. Назовите новый интерфейс «IMyObject2». Укажите для нового интерфейса родительский интерфейс – IUnknown.

    4. Выделите эту вершину, перейдите на правой пане­ли на страницу Flags и выключите на ней флаги Dual и OleAutomation, чтобы не усложнять нашу задачу.

    5. Введите в новом интерфейсе так же, как делали раньше, два метода Mult — перемножение чисел, и Div — деление.

    6. Вы описали второй интерфейс. Теперь надо ввести его в ваш объект. Выделите в левой панели вершину объекта MyObject и перейдите в правой панели на страни­цу Implements. Щелкните на ней правой кнопкой мыши и выберите в контекстном меню раздел InsertInterface. Перед вами откроется окно со списком интерфейсов, ко­торые вы можете добавить в свой объект. Выберите из него созданный вами интер­фейс IMyObject2. Интерфейс включится в ваш объект.

    7. Описание объекта закончено. Теперь надо написать реализацию введенных методов. Щелкните на быстрой кнопке Refresh Implementation — обновить реализа­цию. Перейдите в редактор кода и посмотрите модуль объекта. Вы увидите в объ­явлении класса ссылку на оба интерфейса, объявления введенных вами методов, а в разделе implementation найдете заготовки реализации этих методов. Напишите в них соответствующие операторы. В результате модуль объекта приобретет вид:

    unit Unit1;
    {$WARN SYMBOL_PLATFORM OFF}
    interface
    uses

    Windows, ActiveX, Classes, ComObj, PMyComServ_TLB, StdVcl;
    type

    TMyObject = class(TTypedComObject, IMyObject, IMyObject2)

    protected

    function Add(Number1, Number2: Single): Single; stdcall;

    function Div_(Number1, Number2: Single): Single; stdcall;

    function Mult(Number, Number2: Single): Single; stdcall;

    function Sub(Number1, Number2: Single): Single; stdcall;

    {Declare IMyObject methods here}

    end;
    implementation
    uses ComServ;
    function TMyObject.Add(Number1, Number2: Single): Single;

    begin

    Result:=Number1+Number2;

    end;
    function TMyObject.Div_(Number1, Number2: Single): Single;

    begin

    Result:=Number1/Number2;

    end;
    function TMyObject.Mult(Number, Number2: Single): Single;

    begin

    Result:=Number*Number2;

    end;
    function TMyObject.Sub(Number1, Number2: Single): Single;

    begin

    Result:=Number1-Number2;

    end;
    initialization

    TTypedComObjectFactory.Create(ComServer, TMyObject, Class_MyObject,

    ciMultiInstance, tmApartment);

    end.

    1. Обратите внимание, что Delphi автоматически изменила имя метода Div на Div_, так как мы случайно задали методу имя, совпадающее с именем соответствующей операции Object Pascal. Чтобы в кодах не возникала двусмысленность, Delphi добавила в конце имени метода символ подчеркивания.

    2. Теперь все сделано, объект в составе сервера СОМ создан. Выполните компиляцию проекта (Project|Compile All Project).

    3. Осталось зарегистрировать сервер в системе. Это можно сделать командой Run | Register ActiveX Server главного меню Delphi. Если вы в дальнейшем надумаете удалить его (вряд ли наш тестовый сервер представляет какую-то ценность), вы должны будете выполнить команду Run | Unregister ActiveX Server.

    Отметим еще, что для распространения вашего проекта между пользователямивам потребуется библиотека типов на языке IDL Трансляция ее осуществляется быстрой кнопкой Export To IDL — крайняя правая на рисунке 3.

    1. Осталось проверить работу нашего сервера. Создайте тестовое приложение, включающее два окна Edit, в которых пользователь может задавать числа, две кнопки, одна из которых выполняет методы первого, а другая — второго интерфейса, и две метки для отображения результатов (рисунок 4.).



    Рисунок 4 - Тестовый пример
    Код этого приложения может сеть вид:

    unit Unit3;
    interface
    uses

    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

    Dialogs, StdCtrls,PMyComServ_TLB;
    type

    TForm1 = class(TForm)

    Edit1: TEdit;

    Edit2: TEdit;

    Label1: TLabel;

    Label2: TLabel;

    Button1: TButton;

    Button2: TButton;

    procedure FormCreate(Sender: TObject);

    procedure Button1Click(Sender: TObject);

    procedure Button2Click(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

    end;
    var

    Form1: TForm1;

    Interface1:IMyObject;

    Interface2:IMyObject2;
    implementation
    {$R *.dfm}
    procedure TForm1.FormCreate(Sender: TObject);

    begin

    Interface1:=CoMyObject.Create;

    Interface1.QueryInterface(ImyObject2,Interface2);

    end;
    procedure TForm1.Button1Click(Sender: TObject);

    begin

    Label1.Caption:=FloatToStr(Interface1.Add(StrToFloat(Edit1.Text),StrToFloat(Edit2.Text)));

    Label2.Caption:=FloatToStr(Interface1.Sub(StrToFloat(Edit1.Text),StrToFloat(Edit2.Text)));

    end;
    procedure TForm1.Button2Click(Sender: TObject);

    begin

    Label1.Caption:=FloatToStr(Interface2.Mult(StrToFloat(Edit1.Text),StrToFloat(Edit2.Text)));

    Label2.Caption:=FloatToStr(Interface2.Div_(StrToFloat(Edit1.Text),StrToFloat(Edit2.Text)));

    end;
    end.

    1. Обратите внимание прежде всего на то, что в оператор uses включена ссылка на модуль созданной вами библиотеки типов PMyComServ_TLB.pas. Далее после объ­явления класса формы вводятся две переменные Interface1 и Interface2 соответст­венно типов IMyObject и IMyObject2, объявленных в вашем объекте СОМ.

    2. Процедура FormCreate является обработчиком события OnCreate формы. Первый оператор этого обработчика создает CoClass класса CoMyObject и возвра­щает указатель на интерфейс по умолчанию IMyObject в переменную Interfacel.

    3. Чтобы получить указатель на второй интерфейс, используется функция Querylnterface первого интерфейса, в которую передаются как параметры имя второго ин­терфейса IMyObject2 и переменная Interface2. В результате переменной Interfaсе2 присваивается указатель на интерфейс IMyObject2.

    Код примера очевиден: при щелчках на той или иной кнопке в метки Label1 и Label2 заносятся результаты выполнения соответствующих мето­дов интерфейсов с параметрами, получаемыми из окон Editl и Edit2.
    Для взаимодействия .NET с COM выполните следующие действия:

    1. Создайте проект в C# , изображенный на рисунке 5.



    Рисунок 5 – Пример COM-клиента на C#

    1. Выполните раннее связывание с СOM-сервером при помощи диалогового окна Add Reference (см. рисунок 6).





    Рисунок 6- Вызов диалогового окна Add Reference


    1. В появившемся диалоговом окне выбираете нужный COM-сервер (рис. 7).

    Рисунок 7 – Обращение к COM-серверу средствами Visual Studio .NET


    1. Для упрощения доступа к COM-серверу добавьте строку:

    namespace com

    {

    using PMyComServ; // !!!!!

    public partial class Form1 : Form

    {

    public Form1()

    {

    InitializeComponent();

    }

    1. Объявите глобальные переменные:

    MyObject m;

    IMyObject i;

    IMyObject2 j;

    1. Для события Click кнопки Button1 (Интерфейс1) напишите следующий программный код:

    private void button1_Click(object sender, EventArgs e)

    {

    // Создаем объект MyObject

    m = new MyObject();

    // Явным образом получаем ссылку на интерфейс IMyObject

    i = m;

    float s1 = Convert.ToSingle(textBox1.Text);

    float s2 = Convert.ToSingle(textBox2.Text);

    // Вызываем методы интерфейса IMyObject

    label1.Text = Convert.ToString(i.Add(s1, s2));

    label2.Text = Convert.ToString(i.Sub(s1,s2));

    }


    1. Для события Click кнопки Button2 (Интерфейс2) напишите следующий программный код:

    private void button2_Click(object sender, EventArgs e)

    {

    // Создаем объект MyObject

    m = new MyObject();

    // Явным образом получаем ссылку на интерфейс IMyObject

    i = m;

    // Получаем ссылку на интерфейс IMyObject2

    // через интерфейс IMyObject

    j = (IMyObject2)i;

    float s1 = Convert.ToSingle(textBox1.Text);

    float s2 = Convert.ToSingle(textBox2.Text);

    label1.Text = Convert.ToString(j.Mult(s1, s2));

    label2.Text = Convert.ToString(j.Div(s1, s2));

    }


      1   2   3   4   5   6   7   8   9   ...   13


    написать администратору сайта