Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Примеры статического и динамического связывания DLL




 

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

1. Выполним команду Вид/Менеджер проекта. Откроется окно Менеджера проекта с одной вершиной MyDLL.dll. Развернем её (рис.10.5) и снова свернем.

 

Рис.10.5 – окно Менеджера проекта с загруженной DLL

 

Рис.10.6 – в окне Менеджера проекта появилась новая вершина

 

2. В окне Менеджера проекта нажмем кнопку Новый и в окне Новые элементы на странице Новый выберем пиктограмму Приложение. Нажмем ОК. На экране появится пустая форма. Выполним команду Вид/Менеджер проекта и увидим, что в окне Менеджера проекта появилась вершина Project1.exe, соответствующая создаваемому тестовому приложению (рис.10.6).

3. Выполним команду Файл/Сохранить проект как и сохраним модуль тестового приложения под именем UTestDLL, а проект – под именем PTestDLL.

 

Рис.10.7 – окно Менеджера проекта с загруженной DLL и тестом

 

4. Введем команду Файл/Сохранить все и сохраним проект под именем TESTDLL. Снова выполним команду Вид/Менеджер проекта и в окне Менеджера проекта увидим загруженную DLL и вершину PTestDLL.exe, соответствующую создаваемому тестовому приложению (рис.10.7).

5. Разместим на форме окно редактирования Edit1 и кнопку Button1 (рис.10.8).

а) б)

Рис.10.8 – тестовое приложение DLL: исходный текст в окне (а)

и результат кодировки (б)

 

В модуле приложения в обработчик щелчка на кнопке поместим оператор:

Edit1->Text = Code_Dec(Edit1->Text.c_str(),’A’);

Он берет текст, занесенный пользователем в окно редактирования Edit1, кодирует его с помощью функции Code_Dec и возвращает закодированную строку в Edit1.

6. Включим в модуль приложения после директивы препроцессора #pragma hdrstop директиву, подключающую заголовочный файл библиотеки:

#include “UMyDLL.h”

Приведем заголовочный файл модуля UTestDLL.h:

//---------------------------------------------------------------------------

#ifndef UTestDLLH

#define UTestDLLH

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

//---------------------------------------------------------------------------

class TForm1: public TForm

{

__published: // IDE-managed Components

TEdit *Edit1;

TButton *Button1;

void __fastcall Button1Click(Tobject *Sender);

private: // User declarations

public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

 

и файл реализации модуля UTestDLL.cpp:

 

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include “UMyDLL.h”

#include “UTestDLL.h”

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource “*.dfm”

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(Tcomponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(Tobject *Sender)

{

Edit1->Text = Code_Dec(Edit1->Text.c_str(),’A’);

}

//---------------------------------------------------------------------------

 

7. Осталось подключить к тестирующему приложению файл .lib, обеспечивающий статическое связывание библиотеки. Для этого сначала нужно активизировать приложение в окне Менеджера проекта, выделив вершину проекта PTestDLL.exe и нажав на кнопку Активизировать (рис.10.9).

 

Рис.10.9 – подготовка к активизированию приложения

 

8. Введём команду Проект/Добавить к проекту…. Во всплывшем диалоговом окне выберем шаблон файлов «Файл библиотеки (*.lib)» и выберем файл MyDLL.lib. Файл библиотеки окажется включенным в тестирующее приложение (рис.10.10). Это обеспечит при запуске приложения статическое связывание библиотеки.

9. Теперь можно сохранить проект, откомпилировать и выполнить его. Результаты работы приложения показаны на рис.10.8.

 

Рис.10.10 – файл библиотеки включен в тестирующее приложение

 

10. Перейдем к рассмотрению варианта динамического связывания. В окне Менеджера проекта нажмем кнопку Новый и в окне Новые элементы на странице Новый выберем пиктограмму Приложение. Нажмем ОК. На экране появится пустая форма.

11. Выполним команду Файл/Сохранить проект как и сохраним (в том же каталоге, где находится DLL) модуль под именем UTestDLL2, а проект – под именем PTestDLL2. С помощью окна Менеджера проекта убедимся, что второе тестирующее приложение добавлено (рис.10.11).

 

Рис.10.11 - окно Менеджера проекта с загруженной DLL,

первым тестом PTestDLL.exe и вторым тестом PTestDLL2.exe

Рис.10.12 – тестовое приложение динамического связывания DLL

12. Разместим на форме окно редактирования Edit1 и три кнопки Button1,2,3 (рис.10.12). Кнопка Загрузить (имя BLoad) будет обеспечивать загрузку DLL, кнопка Выгрузить (имя BFree) будет выгружать библиотеку из памяти, а кнопка Кодировать/Декодировать (имя Button1) аналогична той, которая была в первом приложении.

13. В заголовочном файле второго приложения в описание класса формы нужно внести объявления (см. ниже).

 

//---------------------------------------------------------------------------

#ifndef UTestDLL2H

#define UTestDLL2H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

//---------------------------------------------------------------------------

class TForm2: public TForm

{

__published: // IDE-managed Components

TEdit *Edit1;

TButton *Button1;

TButton *BLoad;

TButton *BFree;

void __fastcall BLoadClick(TObject *Sender);

void __fastcall BFreeClick(TObject *Sender);

void __fastcall Button1Click(TObject *Sender);

private: // User declarations

// Объявление указателя на DLL

HINSTANCE dllInstance;

// Объявление указателя на функцию

typedef char* (__import FType(char *, char));

FType * C_D;

public: // User declarations

__fastcall TForm2(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm2 *Form2;

//---------------------------------------------------------------------------

#endif

 

//---------------------------------------------------------------------------

 

Переменная dllInstance будет содержать указатель на загруженный модуль DLL. Вводимый тип FType соответствует типу функции Code_Dec, которая будет вызвана из библиотеки. А переменная C_D будет содержать указатель на эту функцию.

14. Приведем файл реализации модуля формы второго приложения:

 

#include <vcl.h>

#pragma hdrstop

#include "UTestDLL2.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm2 *Form2;

//---------------------------------------------------------------------------

__fastcall TForm2::TForm2(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm2::BLoadClick(TObject *Sender)

{

// Загрузка DLL

dllInstance = LoadLibrary("MyDLL.dll");

if(dllInstance)

// получение указателя на функцию

C_D = (FType *)GetProcAddress(dllInstance, "_Code_Dec");

else ShowMessage(«Не удалось загрузить 'MyDLL.dll'»);

}

//---------------------------------------------------------------------------

void __fastcall TForm2::BFreeClick(TObject *Sender)

{

// выгрузка DLL

FreeLibrary(dllInstance);

C_D = NULL;

}

//---------------------------------------------------------------------------

void __fastcall TForm2::Button1Click(TObject *Sender)

{

if (C_D)

Edit1->Text = C_D(Edit1->Text.c_str(),'A');

else ShowMessage(

" Функция 'Code_Dec' из 'MyDLL.dll' недоступна");

}

//---------------------------------------------------------------------------

Обработчик BLoadClick загружает библиотеку функцией LoadLibrary. Если загрузить библиотеку не удалось, то значение dllInstance окажется равным NULL. В этом случае пользователю выдается сообщение «Не удалось загрузить 'MyDLL.dll'». А если загрузка прошла успешно, то методом GetProcAddress в переменную C_D заносится указатель на импортируемую функцию.

Обработчик Button1Click обеспечивает вызов функции с помощью указателя C_D. А если указатель равен NULL (например, в библиотеке не оказалось требуемой функции, что в нашем случае невозможно, или перед выполнением Button1Click не была загружена библиотека, что в нашем случае возможно), то пользователю выдается соответствующее сообщение об ошибке.

Обработчик BFreeClick выгружает функцией FreeLibrary из памяти модуль DLL и обнуляет указатель C_D.

15. Выполним данное приложение и убедимся, что все работает нормально (рис.10.12).

16. Проведите эксперимент, размещая исполняемый файл тестового приложения и файл библиотеки в различных каталогах.

 

Контрольные вопросы

 

1. Что представляет собой динамически присоединяемая библиотека DLL?

2. Расскажите о назначении DLL. Как она может использоваться?

3. Расскажите о способах связи DLL с приложением. Какой способ предпочтительнее и почему?

4. Как реализовать статическое связывание библиотеки с приложением?

5. Как реализовать динамическое связывание библиотеки с приложением?

6. Какие указатели и как используются при динамическом связывании?

7. Расскажите о порядке создания DLL.

8. Как создается и что содержит файл реализации DLL?

9. Что содержит заголовочный файл библиотеки?

10. Когда и как заголовочный файл библиотеки включается в библиотеку?

11. Когда и как заголовочный файл библиотеки включается в приложение?

12. Как создается приложение для статического связывания с библиотекой DLL?

13. Как создается приложение для динамического связывания с библиотекой DLL?

14. Как разместить исполняемый файл тестового приложения и файл библиотеки в различных каталогах? Приведите пример.

 





Поделиться с друзьями:


Дата добавления: 2015-10-01; Мы поможем в написании ваших работ!; просмотров: 652 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Неосмысленная жизнь не стоит того, чтобы жить. © Сократ
==> читать все изречения...

2285 - | 1991 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.012 с.