Работа с DLL в Delphi [2]



Для начала немного теории. Подобный вызов библиотек производится с помощью WinAPI - функций:

1) LoadLibrary (libfilename: Pchar);

2) GetProcAddress(module: Thandle; ProcName: Pchar);

3) FreeLibary (LibModule: Thandle);

Используются они именно в таком порядке.

1-ая функция, LoadLibrary, загружает библиотеку по адресу, переданному в параметре, в память. Именно с этого момента функции и процедуры в библиотеки доступны для считывания и вызова. В этом и есть плюс данного метода - dll сидит в памяти не постоянно, а лишь тогда, когда это нам нужно.

2-ая функция, GetProcAddress, считывает адрес библиотечной функции, которую мы собираемся использовать. Если функция считалась успешно, то возвратиться дескриптор (грубо говоря - адрес в памяти) этой функции.

3-я функция, FreeLibrary делает dll не действительной, освобождая всю память, которую использовала библиотека. После удачного вызова функции и успешной работы, всегда не забываем очищать память. После вызовы данной функции, как следовательно, библиотека больше не доступна.

Ну что ж, использовать мы будем ту же, крайне не замысловатую процедурку, которую использовали в предыдущем уроке (ссылка, если кто ещё не ознакомился). Приведу, всё же, код библиотеки:

library Project2;
 
uses
  SysUtils,
  Classes,
  Dialogs;
 
{$R *.res}
 
procedure One; stdcall; export;
begin
  ShowMessage('1');
end;
 
exports One;
begin
end.


Т.е. у нас фактически лишь 1 процедура, которая выбрасывает в сообщении цифру 1.

Итак, а теперь пробуем вызвать её. Создаём новый проект, кидаем на форму кнопку:



Да, друзья, ностальгируем - старый, добрый, Delphi7 (пришлось работать в нём, по техническим причинам :) )

В глобальных переменных задаём следующие переменные:

var
  one: procedure; // объявляем процедуру
  Handle_: THandle; //Переменная типа THandle (грубо говоря, идентификатор какого-либо объекта (caption у формы - тоже идентификатор, к слову :))


Тип THandle, грубо говоря, есть идентификатор какого-либо объекта. Т.е. это некоторое имя объекта, содержащее указатель на него в памяти (дескриптор).

Теперь код на обработчик события onclick у кнопки :

begin
@one:= nil; // @ - указатель на адрес объекта (в данном случае процедуры one). Чистим этот самый адрес.
Handle_:= LoadLibrary('Project2.dll'); // Загружаем в переменную нашу библиотеку (которую перед этим мы закинули в папку с проектом)
if Handle_ >= 32 then // Если handle >= 32 (если загрузка прошла успешно, то)
  begin
    @one:= GetProcAddress(Handle_,'One'); // В процедуру записываем адрес библиотечной функции 'One' (2-ой параметр), из библиотеки по адресу в переменной Handle_ 
    if @one <> nil then // Если память, выделенная под процедуру не пуста, то
    one // Выполняем эту процедуру 
    else ShowMessage('Ошибка!'); //Иначе выводим окно, сообщающее об ошибке
  end;
  FreeLibrary(Handle_); //По-окончанию обязательно очищаем память.
  end;


Ну что, не так уж всё и сложно? Проверяем:



Всё сработало как часы :)

На этом рассмотрение вызовов библиотек мы заканчиваем. Спасибо за внимание.
Теги:
статье, прошлой
Добавлено: 24 Февраля 2015 20:21:21 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...