Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Динамические библиотеки



При разработке программы можно использовать динамические библиотеки (dll). При использовании dll следует учитывать следующие моменты:

· динамические библиотеки хранятся в памяти в единственном экземпляре;

· они используют адресное пространство вызывающей программы;

· не работают с глобальными переменными вызывающей программы;

· подключаются к основной программе во время исполнения (runtime);

· должны обрабатывать все исключительные ситуации внутри себя;

· учитывают регистр экспортируемых функций.

Чтобы создатьdll-библиотеку в Delphi, необходимо последовательно выбрать File –> New –> Other –> DLL wizard. Delphi создаст заготовку для разработки библиотеки и откроет окно редактора кода. После ключевого слова libraryнеобходимо указать имя будущей библиотеки. В теле library реализовать необходимые функции и после ключевого слова exports перечислить подпрограммы, которые библиотека должна поставлять вызывающей программе. При реализации функций необходимо учитывать соглашение о вызовах. Если прототип реализуемой функции выглядит как function SomeFunc(X: SomeParam): SomeParam; stdcall;, то соглашение stdcall (стандарт Windows) определяет: направление передачи параметров подпрограмме вызывающей программой – справа налево; передачу параметров через стек; очистку стека подпрограммой.

Для отладки dll необходимо задать host приложение, которое будет осуществлять вызов dll: Run –> Parameters, и, воспользовавшись кнопкой «Browsе», загрузить в поле «Host Application» полное имя вызывающей программы. После компиляции проекта библиотеки Delphi создаст файл с расширением dll – это и есть динамическая библиотека. Вызвать подпрограмму избиблиотеки можно явным или неявным способом. Механизм неявного вызова наиболее прост, т. к. выполняется автоматически и основан на имеющейся в приложении информации о вызываемых функциях и динамических библиотеках. Однако разработчик не имеет возможности влиять на ход загрузки dll. Если операционная система не смогла загрузить библиотеку, просто выдается сообщение об ошибке. Единственный способ повлиять на процесс загрузки – использовать секцию инициализации библиотеки. При неявном вызове Delphi откомпилирует код так, что библиотека будет загружаться во время запуска программы. Для повышения скорости загрузки и для экономии памяти библиотеку необходимо подключать динамически, т.е. явно. Это позволяет производить загрузку библиотеки только в тот момент, когда необходимо, после чего библиотеку можно выгрузить и освободить память.

Разработаем библиотеку Neuman.dll. Разместим в ней процедуру CalcNeuman для генерации методом Неймана псевдослучайного числа из экспоненциального распределения. Эту процедуру библиотека будет экспортировать.

library Neuman;

uses

SysUtils, Classes, Math;

{$R *.res}

function ExpDistr(l, x: Double): double;

begin

Result:= l * exp(-l*x);

end;

procedure CalcNeuman(l: double; var x: double; var y: double); stdcall

begin

while true do begin

x:= random;

y:= random;

if y < ExpDistr(l, x) then break;

end;

end;

exports CalcNeuman;

begin

end.

В приведенном примере реализована также функция ExpDistr, которая используется внутри библиотеки для расчета экспоненциального распределения, и не может быть вызвана за ее пределами. При неявном вызове поцедуры CalcNeuman из библиотеки Neuman.dll описание ее в основной программе будет иметь вид:

procedure CalcNeuman(l: double; var x: double; var y: double); stdcall; external 'Neuman.dll';

А вызов:

for i:= 1 to stat do begin

CalcNeuman(0.76, x, y);

...

end;

В случае использования явного вызова объявление прототипа выглядит так:

type

TFuncType = function (x: SomeType):SomeType; stdcall;

var

dllhandle: THandle;

MyFunc: TFuncType;

error: DWORD;

И вызов:

dllhandle:=LoadLibrary('Neuman.dll');

if dllhandle <> 0 then begin //есть ли библиотека?

@MyFunc:= GetProcAddress(dllhandle, 'CalcNewman'); //получить // адрес экспортируемой процедуры

if Addr(MyFunc) = nil then begin

ShowMessage('CalcNewman в Neuman.dll не найдена.');

FreeLibrary(dllhandle);

Close;

end;

end

else begin // Neuman.dll не найдена

error:= GetLastError;

if ((error= ERROR_DLL_NOT_FOUND) or

(error = ERROR_MOD_NOT_FOUND)) then

ShowMessage(' Neuman.dll не найдена.');

end;

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

Для освобождения занимаемой библиотекой памяти необходимо по окончании работы программы выполнить проверку на наличие открытых библиотек и при необходимости отключить их. Удобно назначить данную функцию обработчику события «Закрытие формы»:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

if dllhandle <> 0 then FreeLibrary(dllhandle);

end;





Дата публикования: 2014-11-03; Прочитано: 350 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.007 с)...