Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
При разработке программы можно использовать динамические библиотеки (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 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!