Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Задачник по программированию.doc
Скачиваний:
17
Добавлен:
17.05.2015
Размер:
2.78 Mб
Скачать

Порядок выполнения работы

  1. На основе варианта задания из лабораторной работы 15 создать библиотеку динамической компоновки, в которую поместить табулируемую функцию и функции, связанные с проверками области допустимых значений. Статический вызов библиотеки разместить в основном модуле. Построить график функции. Для этого добавить в пункт меню «Вычисления» и контекстное меню пункт «Построение графика». Диаграмму разместить в отдельном окне.

  2. Обработать все возможные исключительные ситуации.

Приблизительный вид форм показан на рис. 20.6.

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

  1. Создание библиотеки динамической компоновки.

  2. Экспортирование функций.

  3. Статическое подключение библиотеки.

  4. Компонент TChart (диаграмма). Особенности его использования для построения графиков.

  5. Основные свойства и методы диаграммы.

Лабораторная работа № 21Использование форм в библиотеках динамической компоновки (Dll). Динамическое подключение Dll.

Цель работы: приобретение навыков создания DLL и их динамического подключения, изучение особенностей использования форм в библиотеках.

Теоретические сведения Динамический вызов библиотеки

При динамическом вызове кроме собственно вызова функции необходимо обеспечить:

  • загрузку библиотеки;

  • получение адреса функции;

  • выгрузку библиотеки.

Загрузку библиотеки выполняет API-функция LoadLibrary(lpLibFileName: pchar): HMODULE, которая загружает в оперативную память библиотеку с именем lpLibFileName. В качестве результата функция возвращает ссылку HMODULE на модуль библиотеки при успешной загрузке и 0 — при ошибке.

Выгружается библиотека API-функцией FreeLibrary(hLibModule: HMODULE): Bool, которая удаляет из оперативной памяти библиотеку, модуль которой ука­зывает параметр HMODULE. В случае успешной выгрузки функция возвращает True и False — в противном случае.

Получение адреса функции выполняется API-функцией GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR): FARPROC, которая ищет в библиотеке, модуль которой задан параметром hModule, функцию, имя которой указано параметром lpProcName, и в качестве результата возвращает указатель на функцию. Если по­иск оказался безрезультатным, то возвращается Nil.

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

Пример 21.1. Используем динамически функции, описанные в библиотеке примера 20.2. Экранная форма программы такая же, как и в примере 20.3 (рис. 20.5). Фрагмент кода с использованием функций из библиотеки:

// Описание типов внешних (из библиотек) функций

type TAddInt=function(p1,p2:integer):integer;

TAddReals=function(p1,p2:real):real;

. . .

private

{ Описание ссылки на модуль DLL }

DLLHandle:THandle;

//1-й вариант переменной для приведения типа функции

ExtFuncAddInt:TAddInt;

//2-й вариант переменных для приведения типа функции

ExtFuncAddRealPoint:TFarProc;

ExtFuncAddReal:TAddReals;

public

{ Public declarations }

end;

. . .

Implementation

{$R *.dfm}

procedure TUntUseDllMain.BtnAddIntClick(Sender: TObject);

var N1,N2,Res:integer;

begin

//загрузка библиотеки

DllHandle:=LoadLibrary('MyDll');

if (DllHandle=0) then begin

ShowMessage('Ошибка загрузки библиотеки MyDLL!!!');

exit;

end;

try

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

// и преобразование его к соответствующему типу

@ExtFuncAddInt:=GetProcAddress(DllHandle,Pchar('AddInt'));

try

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

N1:=strtoint(EdtInt1.Text);

N2:=strtoint(EdtInt2.Text);

except

ShowMessage('Ошибка данных!!!');

exit;

end;

//вызов функции AddInt

Res:=ExtFuncAddInt(N1,N2);

EdtResInt.Text:=inttostr(Res);

//выгрузка бибилиотеки

finally

FreeLibrary(DllHandle);

end;

end;

procedure TUntUseDllMain.BtnAddRealClick(Sender: TObject);

var N1,N2,Res:real;

begin

//загрузка библиотеки

DllHandle:=LoadLibrary('MyDll');

if (DllHandle=0) then begin

ShowMessage('Ошибка загрузки библиотеки MyDLL!!!');

exit;

end;

try

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

// и преобразование его к соответствующему типу

ExtFuncAddRealPoint:=GetProcAddress(DllHandle,Pchar('AddReals'));

if (ExtFuncAddRealPoint<>nil) then

ExtFuncAddReal:=TAddReals(ExtFuncAddRealPoint);

try

//преобразование данных к вещественному типу

N1:=strtoFloat(EdtReal1.Text);

N2:=strtoFloat(EdtReal2.Text);

except

ShowMessage('Ошибка данных!!!');

exit;

end;

//вызов функции AddReal

Res:=ExtFuncAddReal(N1,N2);

EdtResReal.Text:=Floattostr(Res);

//выгрузка библиотеки

finally

FreeLibrary(DllHandle);

end;

end;

end.