ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
Теоретические сведения. Динамический вызов библиотекиДинамический вызов библиотеки При динамическом вызове кроме собственно вызова функции необходимо обеспечить: · загрузку библиотеки; · получение адреса функции; · выгрузку библиотеки. Загрузку библиотеки выполняет 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. Использование форм в библиотеках Библиотека может содержать формы, при этом форма добавляется к библиотеке и конструируется обычным для проекта способом, но обязательно надо включить в модуль формы экспортируемые функции (как минимум одну), служащие для управления формой извне библиотеки. В основной модуль экспортируется функция управления формы и ее подключение осуществляется так же, как и любой другой функции. Пример 21.2. Создадим программу, в которую будет загружаться форма из библиотеки. Экранная форма основной программы показана на рис. 21.1, а форма, загружаемая из библиотеки — на рис. 21.2. Код библиотеки, содержащей форму:
library DLLForm; { библиотека с использованием формы } uses ShareMem, SysUtils, Classes, //подключение модуля с формой untFrmDLL in 'untFrmDLL.pas' {FrmDLL}; {$R *.res} //экспортирование функции для внешнего управления формой exports ShowFrmInDLL; Begin End. unit untFrmDLL; interface ... var FrmDLL: TFrmDLL; function ShowFrmInDLL(name:string):TModalResult; implementation {$R *.dfm} function ShowFrmInDLL(name:string):TModalResult; begin FrmDll:=TFrmDll.Create(Application); FrmDll.Caption:=name; Result:=FrmDll.ShowModal; FrmDll.Free; end; procedure TFrmDLL.FormCreate(Sender: TObject); begin btnOK.ModalResult:=mrOk; btnCancel.ModalResult:=mrCancel; end; End. Рис. 21.1. Экранная форма основной программы примера 21.2 Рис. 21.2. Экранная форма примера 21.2, загружаемая из библиотеки Порядок выполнения работы 1. На основе варианта задания из лабораторной работы 20 создать библиотеку динамической компоновки, в которую поместить форму с графиком. Динамический вызов библиотек (с функцией и формой) разместить в основном модуле. 2. Обработать все возможные исключительные ситуации. Контрольные вопросы 1. Особенности создания библиотеки динамической компоновки с формой. 2. Экспортирование функций. 3. Загрузка библиотеки в оперативную память. 4. Выгрузка библиотеки из оперативной памяти. 5. Получение адреса внешней функции. Лабораторная работа № 22 Цель работы: закрепление навыков объектно-ориентированного программирования. Изучение особенностей создания и использования компонентов IDE Delphi. Не нашли, что искали? Воспользуйтесь поиском:
|