Program TestDynamicImport;

Uses Windows;

Type

TBubleSortProc = procedure (var Arr: array of Integer); stdcall;

TQuickSortProc = procedure (var Arr: array of Integer); stdcall;

Var

BubleSort: TBubleSortProc; // указательнафункцию BubleSort

QuickSort: TQuickSortProc; // указательнафункцию QuickSort

LibHandle: HModule; // описательбиблиотеки

Arr: array [0..9] of Integer;

I: Integer;

Begin

LibHandle := LoadLibrary('SortLib.dll');

if LibHandle <> 0 then

Begin

@BubleSort := GetProcAddress(LibHandle, 'BubleSortIntegers');

@QuickSort := GetProcAddress(LibHandle, 'QuickSortIntegers');

if (@BubleSort <> nil) and (@QuickSort <> nil) then

Begin

Randomize;

for I := Low(Arr) to High(Arr) do Arr[I] := Random(100);

BubleSort(Arr);

End

else Writeln('Ошибкаотсутствияпроцедурывбиблиотеке.');

FreeLibrary(LibHandle);

End

else Writeln('Ошибказагрузкибиблиотеки.');

End.

В программе определены два процедурных типа данных, которые по списку параметров и правилу вызова (stdcall) соответствуют подпрограммам сортировки BubleSort и QuickSort в библиотеке:

type

TBubleSortProc = procedure (var Arr: array of Integer); stdcall;

TQuickSortProc = procedure (var Arr: array of Integer); stdcall;

Эти типы данных нужны для объявления процедурных переменных, в которых сохраняются адреса подпрограмм:

Var BubleSort: TBubleSortProc;

QuickSort: TQuickSortProc;

В секции var объявлена также переменная для хранения целочисленного описателя библиотеки, возвращаемого функцией LoadLibrary: LibHandle: HModule;

Программа начинает свою работу с того, что вызывает функцию LoadLibrary, в которую передает имя файла DLL-библиотеки. Функция возвращает описатель библиотеки, который сохраняется в переменной LibHandle:LibHandle := LoadLibrary('SortLib.dll');

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

@BubleSort := GetProcAddress(LibHandle, 'BubleSortIntegers');

@QuickSort := GetProcAddress(LibHandle, 'QuickSortIntegers');

Использование символа @ перед именем каждой переменной говорит о том, что выполняется не вызов подпрограммы, а работа с ее адресом. Если этот адрес отличен от значения nil, значит подпрограмма с указанным именем была найдена в библиотеке и ее можно вызвать путем обращения к процедурной переменной:

if (@BubleSort <> nil) and (@QuickSort <> nil) then

begin

...

BubleSort(Arr);

...

end

По окончании сортировки программа выгружает библиотеку вызовом функции FreeLibrary.

Динамический импорт в сравнении со статическим требует значительно больше усилий на программирование, но он имеет ряд преимуществ:

·Более эффективное использование ресурсов оперативной памяти по той причине, что библиотеку можно загружать и выгружать по мере надобности;

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

Динамический импорт отлично подходит для работы с библиотеками драйверов устройств. Он, например, используется самой средой Delphi для работы с драйверами баз данных.








Дата добавления: 2015-09-07; просмотров: 947;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

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

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.007 сек.