Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы IT / ЛабаDelphi12.doc
Скачиваний:
62
Добавлен:
06.02.2015
Размер:
336.9 Кб
Скачать
  1. Динамически подключаемые библиотеки

Часто, во время выполнения программы бывают случаи, когда требуется загрузить библиотеку в оперативную память, попользоваться ей некоторое время, а затем выгрузить её из оперативной памяти, так как в ней уже нет необходимости.

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

function LoadLibrary(lpLibFileName: PChar): HMODULE; stdcall;

Функция загружает библиотеку с именем lpLibFileNameв оперативную память и в качестве значения возвращает дескриптор загруженной библиотеки.

function GetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;

Зная по значению дескриптора hModule, местонахождение в оперативной памяти загруженной библиотеки, функция возвращает адрес (указатель) конкретной процедуры или функции с именемlpProcNameтипа LPCSTR. (Здесь LPCSTR = PAnsiChar).

function FreeLibrary(hLibModule: HMODULE): BOOL; stdcall;

Функция выгружает из оперативной памяти загруженную библиотеку. Возвращает Falseкак только библиотека выгружена.

Нужно отметить то важное обстоятельство что, данные функции являются частью ядра операционной системы Windows, так как они содержатся в базовом модулеKernel, то есть находятся в библиотекеKernel32.dll.

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

Таким образом, динамический вызов подпрограмм, процедур и функций конкретной библиотеки возможен только через посредника – операционную систему Windows. В ОСLinuxпредусмотрены другие названия подобных системных функций.

Задание 3.1. Подключим динамически библиотеку MainDll.dll к проекту и вызовем функцию суммы SummaX_Y(X,Y:real):real;

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

Скопируйте все файлы вашего первого проекта (вместе с готовой библиотекой MainDll.dll) который вы делали в первом задании, в новую папку.

Загрузите проект в Delphiв режиме программирования.

Учитывая, что нам уже не нужна статическая загрузка библиотеки в момент загрузки внешнего приложения (т.е. данного проекта), то в окне редактора кода модуля удалите все объявления импортируемых процедур и функций с ключевым словом external.

Первое что нужно сделать, так это определить переменную процедурного (procedure) или функционального (function) типа.

Объявите глобальную переменную в секции varс именем SummaX_Y функционального типа function(X,Y:real):real.

Таким образом, в окне редактора кода должна быть следующая запись (рис. 11).

Рис. 11Объявляем глобальную переменную SummaX_Y типаfunction

Далее измените надпись на кнопке на следующую:

«Запуск функции SummaX_Y из динамически подключенной библиотеки MainDll.dll»

Измените обработчик щелчка этой кнопки так, чтобы он выглядел следующим образом:

procedure TForm1.Button1Click(Sender: TObject);

var H:THandle; X,Y:real; S:string;

begin

RichEdit1.Clear;

X:=StrToFloat(Edit1.Text);

Y:=StrToFloat(Edit2.Text);

S:=Edit3.Text;

H:=LoadLibrary('MainDll.dll');

// Определяем дескриптор подключенной библиотеки MainDll.dll

if H <> 0 then begin

{Если дескриптор не равен нулю значит библиотека успешно загрузилась}

@SummaX_Y := GetProcAddress(H, 'SummaX_Y');

{Функцией GetProcAddressопределяем адрес функции с именемSummaX_Yсодержащийся в библиотеке и назначаем этот адрес переменной функционального типаSummaX_Yнашего проекта }

if @SummaX_Y<>nil then

Richedit1.Lines.Add(FloatToStr( SummaX_Y(X,Y)) );

{если адрес @ библиотечной функции успешно получен, то есть не равен нулю, то вызываем функцию SummaX_Y}

FreeLibrary(H); //Выгружаем библиотеку из памяти

end;

end;

Вот и всё! Можете запустить программу на выполнение. Программа должна работать правильно. Вернитесь в РП.

Обратите внимание на оператор @ он возвращает адрес некоторого объекта

(процедуры или функции). Его применение эквивалентно функции Addr(X): Pointer.

В данном примере мы назначаем новый адрес переменной функционального типа из нашего проекта. Именно по этому адресу в оперативной памяти находится код функции из библиотеки.

Задание 3.2 (Самостоятельно). Добавьте на форму еще 2 кнопки Button, при щелчке на которых, аналогично будут вызываться остальные 2 функции из динамически подключенной библиотеки MainDll.dll.

function ProizvX_Y(X,Y:real):real; //функция произведения двух чисел X и Y, и

function Revers(S:string):string; //функция возвращающая строку S задомнаперёд

автор и разработчик лабораторных

работ по Delphi

доцент кафедры Информационных технологий и систем

кандидат физ.-мат. наук

Санников Е.В.

Соседние файлы в папке Лабы IT