Создание dll-библиотеки на Delphi. Создание и использование DLL в Delphi (привязка DLL к программе, динамическая загрузка) Создание активных библиотек в delphi

В среде программирования Delphi предусмотрены встроенные средства для быстрого создания DLL-библиотек.

Давайте для определенности создадим библиотеку, содержащую функцию

GetArea(a, b, c: REAL):REAL.

Данной функции на вход подаются длины сторон треугольника. Функция возвращает площадь заданного треугольника:

p:=(a+b+c)/2;

Result:=SQRT(p*(p-a)*(p-b)*(p-c))

Запускаем D elphi , а дальше действуем нетрадиционно. Выбираем пункты меню F ile N ew O ther , в открывшемся окошке на закладке N ew щелкаем по пиктограмме DLL W izard . (алгоритм зависит от версии)

При этом создается файл заготовки DLL-библиотеки. Он очень похож на обычный модуль (unit ) D elphi , только начинается с оператора Library . Сохраните проект под именем, которое в будущем получит DLL-библиотека, скажем, GetA . Название GetArea использовать нельзя – оно уже занято именем функции.

Теперь после оператора USES пишем текст нашей функции, но с некоторыми изменениями в заголовке:

FUNCTION GetArea(a, b, c:REAL):REAL; export;

Ключевое слово EXPORT указывает на то, что данная функция является экспортируемой и будет видна из внешних программ.

После текста функции припишем

GetArea ;

В операторе EXPORTS перечисляются все процедуры и функции, экспортируемые из библиотеки. Это своего рода каталог нашей библиотеки.

Запустить на выполнение библиотеку невозможно, ее можно только откомпилировать. Для этого выполним пункт меню Project → Build. Если все было сделано правильно, на диске в текущей директории будет создан файл с именем geta.dll. Это и есть наша библиотека.

Важное замечание : существует определенная тонкость при передаче процедурам и функциям, находящимся в библиотеке, параметров типа STRING.

Для того, чтобы можно было передавать параметры типа STRING, придется в операторы USES и библиотеки, и вызывающей ее программы прописать подключение модуля ShareMem, да еще и обязательно так, чтобы этот модуль шел первым в списке. Мало того, вместе с библиотекой придется обязательно прилагать файл borlndmm.dll (он входит в поставку Delphi). Избежать этой ситуации просто: следует для параметров текстового типа использовать типы данных ShortString (это обычная строка, но длиной до 255 символов) и PChar (указатель на текстовую строку).

Вызов dll

Существуют два способа вызова процедур и функций из DLL. В первом случае мы заранее, на этапе разработки программы, знаем, какую DLL будем к ней подключать (чаще всего мы сами и создаем эту DLL). Во втором случае мы подключаемся к произвольной библиотеке, в том числе и "чужой".

Статическое связывание

Для реализации первого способа, называемого статическим связыванием , создайте новое обычное приложение, поместите на форму три поля ввода LabeledEdit1…LabeledEdit3, кнопку и компонент Tlabel. После оператора IMPLEMENTATION добавьте строчку, обеспечивающую импорт функции GetArea из библиотеки geta.dll:

Function GetArea(a,b,c:real):REAL; FAR; EXTERNAL "geta";

Слово EXTERNAL указывает на то, что тело данной функции находится в библиотеке с указанным именем, а слово FAR задает применение "длинных" четырехбайтных адресов, что необходимо, так как вызывающая программа находится на одной странице памяти, а DLL-библиотека – на другой. Разумеется, файл geta.dll надо поместить в ту же директорию, где находятся все файлы текущего приложения.

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

procedure TForm1.Button1Click(Sender: TObject);

Чтобы создать новую библиотеку DLL в Delphi, выберите команду меню File > New > Other . В панели Items Categories окна New Items выберите узел Delphi Projects , после чего дважды щелкните на элементе Dynamic-link Library в правой панели окна.

Мастер DLL Wizard создает главный файл исходного кода библиотеки DLL, который выглядит практически так же, как и исходный код, сгенерированный для обычного приложения. Единственное отличие состоит в том. что этот файл начинается с зарезервированного слова library , а не program .

Library Project1; { Important note about DLL memory management: ShareMem must be the first unit in your library"s USES clause AND your project"s (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } { Важное замечание относительно управления памятью библиотеки DLL: модуль ShareMem должен быть первым модулем в операторе uses вашей библиотеки и в операторе uses вашего проекта (выберите команду меню Project -> View Source (Проект -> Показать исходный код)), если ваша библиотека DLL экспортирует какие-либо процедуры или функции, передающие строки в качестве параметров или результатов выполнения функций. Это относится ко всем строкам, передаваемым или получаемым из вашей библиотеки DLL, и даже к тем строкам, которые вложены в записи и классы. Модуль ShareMem является модулем интерфейса для администратора общей памяти BORLNDMM.DLL, который вы должны развертывать вместе со своей библиотекой DLL. Чтобы не использовать BORLNDMM.DLL, передавайте строковую информацию с помощью параметров PChar или ShortString. } uses SysUtils, Classes; {$R *.res} begin end.

Все, что вам нужно сделать сейчас - это добавить подпрограмму перед блоком begin-end , вот и все. После этого вы получите внутреннюю подпрограмму, которую можно будет использовать в библиотеке DLL, но не во внешних приложениях. Если вы хотите вызывать подпрограмму из других приложении и других библиотек DLL, ее потребуетсл экспортировать. Чтобы экспортировать подпрограмму по имени, добавьте ее в список exports . Список exports имеет такой же синтаксис, что и список uses , за исключением того, что в списке exports любой элемент является подпрограммой, а не модулем.

Список exports обычно ставится непосредственно перед блоком begin-end . Взгляните на листинг 1, в котором представлен исходный код простой библиотеки FirstLib.dll , экспортирующей одну функцию.

Листинг 1. Простая библиотека DLL

Library FirstLib; function Max3(Num1, Num2, Num3: Integer): Integer; stdcall; begin Result:= Num1; if Num2 > Result then Result:= Num2; if Num3 > Result then Result:= Num3; end; { Экспортируем функцию Max3 } exports Max3; begin end.

Когда вы добавите подпрограмму в список exports , вы тем самым экспортируете подпрограмму по ее имени. Вы можете также экспортировать подпрограмму под другим именем с помощью директивы name или посредством порядкового значения, используя директиву index . Однако применять директиву index не рекомендуется.

Ниже показан пример экспортирования директивы посредством порядкового значения или под другим именем:

Exports Max3 name "MyMax3Function", SaySomething index 1;

Статическая загрузка является самым простым из двух возможных способов загрузки библиотеки DLL. Статическую загрузку называют еще динамическим подключением во время загрузки (load-time dynamic linking ), потому что используемые библиотеки DLL автоматически загружаются во время запуска приложения.

Чтобы статически загрузить библиотеку DLL, необходимо скопировать объявление подпрограммы и вызывающее приложение и пометить ее с помощью директивы external , которая сообщает компилятору о том, что подпрограмма находится либо в объектном файле, либо в библиотеке DLL.

Когда вы импортируете подпрограммы из библиотеки DLL, вы должны помечать их директивой external , указывая вслед за ней имя библиотеки DLL, в которой содержится реализация подпрограммы. Далее показан пример импорта функции МахЗ из библиотеки FirstLib.dll :

Function Max3(Num1, Num2, Num3: Integer): Integer; stdcall; external "FirstLib.dll";

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

Function Max(Num1, Num2, Num3: Integer): Integer; stdcall; external "FirstLib.dll" name "Max3";

Вы можете также импортировать функцию из библиотеки DLL. Для этого нужно создать модуль импорта и написать стандартный заголовок подпрограммы в разделе interface , а ее внешнюю реализацию - в разделе implementation этого модуля. В листинге 2 показан полный код модуль импорта библиотеки FirstLib.dll .

Листинг 2. Модуль импорта библиотеки FirstLib.dll.

Unit FirstLibInf; interface function Max3(Num1, Num2, Num3: Integer): Integer; stdcall; implementation const FirstLib = "FirstLib.dll"; {Компилятору сообщается о том, что реализация функции Max3 находится в библиотеке FirstLib.dll} function Max3; external FirstLib; end.

После того как вы создадите библиотеку DLL и ее модуль импорта, протестируйте библиотеку DLL, чтобы убедиться в том. что подпрограмма работает нормально. Поскольку запустить саму библиотеку DLL нельзя, нужно создать тестовое приложение, которое будет обращаться к библиотеке DLL. Быстрее всего сделать это можно, если создать проектную группу, добавив новый проект в текущий проект. Для этого потребуется щелкнуть правой кнопкой мыши на элементе ProjectGroup1 в окне Project Manager (Диспетчер проекта) и выбрать в контекстном меню команду Add New Project , как показано на рис. 1.

Листинг 3. Проверка подпрограммы Max3, импортированной из библиотеки FirstLib.dll.

Unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, FirstLibInf, StdCtrls; type TMainForm = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Max3Button: TButton; procedure Max3ButtonClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var MainForm: TMainForm; implementation {$R *.dfm} procedure TMainForm.Max3ButtonClick(Sender: TObject); var LargestNumber: Integer; begin LargestNumber:= Max3(StrToInt(Edit1.Text), StrToInt(Edit2.Text), StrToInt(Edit3.Text)); MessageDlg(Format("Наибольшее число: %d.", ), mtInformation, , 0); end; end.

Используемая литература: Внутренний мир Borland Delphi 2006. Иван Хладни.

Аббревиатура DLL означает "динамически соединяемая библиотека". Dll в Delphi это файл, содержащий необходимые для работы компьютерной программы процедуры и функции, с которым программа соединяется на этапе выполнения.

Казалось бы, все необходимые подпрограммы можно описать в теле программы, зачем нужно создавать дополнительный dll-файл и соединяться с ним во время выполнения? Делается это для большей гибкости создаваемой программы. Ведь со временем могут измениться некоторые алгоритмы обработки данных. Если процедуры обработки будут содержаться в теле программы, её придётся перекомпилировать, и вновь передавать заказчикам достаточно объёмный файл. Передать же небольшой dll-файл, содержащий только несколько процедур, гораздо проще, и даже в автоматическом режиме.

Кроме того, работа библиотеки dll совершенно не зависит от языка программирования, на котором она будет создана. Потому создание dll для нашей программы мы можем поручить сторонним разработчикам, не думая о языках программирования которыми они владеют. Всё это, конечно, намного ускоряет создание и передачу заказчикам готового проекта

Создание DLL библиотеки

Создание dll в Delphi не сложнее создания дополнительного модуля. Выпоните команду File -> New -> -> Other... В появившепся диалоговом окне выберите пиктограмму DLL Wisard. В результате Delphi создаст заготовку проекта библиотеки DLL:

library Project1;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library"s USES clause AND your project"s (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
SysUtils,
Classes;

{$R *.res}

begin
end
.

Выберите имя для новой библиотеки dll и сохраните в отдельную папку, выполнив команду File -> Save As... В папке появятся 4 файла, среди которых собственно dll-файла не будет. Естественно, ведь это просто текстовые файлы, содержащие описание проекта. Для создания итогового файла библиотеки dll необходимо скомпилировать проект. Выполните команду Project -> Compile Project . В результате в нашей папке появится собственно dll файл, с которым и будет соединяться основная программа.

Пока это пустая библиотека.

...в настоящее время текст находится в стадии редактирования...

Здравствуйте уважаемые коллеги!

В данной статье я постараюсь ответить на вопросы: Что такое DLL ? Для чего она нужна? И как создавать и использовать DLL при помощи Delphi .

Что такое DLL ?

Dynamic Link Library или сокращенно DLL — это библиотека, которая содержит в себе набор данных или функций для использования в других программах.

Области применения:

  • Хранение ресурсов: иконки, звуки, курсоры и т.д. Экономим на размере исполняемых файлов объединяя ресурсы в единую библиотеку.
  • Размещение отдельных модулей программы и форм интерфейса. Получаем возможность частичного обновления приложения, а при динамическом подключении, возможно обновлять модули без перезапуска основной программы.
  • Использование в качестве плагинов (PlugIn). Предоставляем возможность расширять функционал приложения без переписывания основного кода программы.
  • Библиотека может использоваться на разных языках программирования в не зависимости от языка на котором она была написана.

Создание собственной библиотеки DLL.

Для создания библиотеки заходим в меню File -> Other и выбираем Delphi Projects -> Dynamic-link Library .
Откроется текст кода с заготовкой для создания библиотеки:

Library Project1; uses System.SysUtils, System.Classes; {$R *.res} begin end.

Размещение ресурсов

Добавим иконку в библиотеку, которую будем использовать потом в основной программе.
Как добавлять ресурсы в проект подробно описано в статье.

Добавим форму «О программе».
Нажимаем File -> New -> VCL Form . Добавим текст и кнопку «ОК»:

Добавим функцию, которая будет выводить стандартный MessageBox с вопросом, кнопками «Да», «Нет» и с результатом в виде True или False .

Function YesNoDlg(const Question: PChar): boolean; stdcall; begin Result:= (MessageBox(0, Question, "Подтверждение", MB_YESNO + MB_ICONQUESTION) = ID_YES); end;

Обратите внимание на ключевое слово stdcall . Оно определяет как именно будут передаваться параметры и результаты при вызове функций. Более подробно можно почитать на странице wiki Соглашение о вызове.

Так же добавим процедуру, которая будет использоваться как плагин для основной программы. Которая будет добавлять кнопку «О программе» в основное меню программы для вызова созданного нами окна.
Код процедуры:

Procedure PlugIn(Form: TForm); stdcall; var i: integer; mi: TMenuItem; begin for i:= 0 to Form.ComponentCount - 1 do begin if (Form.Components[i].ClassName = "TMenuItem") and (Form.Components[i].Name = "miHelp") then begin mi:= TMenuItem.Create(Form.Components[i]); mi.Caption:= "О программе"; mi.OnClick:= fmAbout.onAboutButtonClick; TMenuItem(Form.Components[i]).Add(mi); Exit; end; end; end;

В процедуру в качестве параметра передается форма программы. Мы проверяем присутствует ли на ней пункт меню с именем «miHelp » и если меню нашлось, то добавляем в него свою кнопку.

Теперь укажем какие функции и процедуры можно использовать из нашей библиотеки.
Добавим строку:

Exports PlugIn, YesNoDlg;

Скомпилируем функцию Project -> Build или с помощью горячей клавиши Shift+F9 .
Если ошибок в коде нет, то в папке проекта должен появиться файл с расширением DLL .

Теперь перейдем к созданию приложения, которое будет использовать нашу библиотеку.

В приложении создадим форму Main в которой добавим компонент со следующими кнопками: Программа -> Выход и Помощь. Для последнего зададим имя — miHelp :

Перейдем к коду формы.

Функции из библиотеки DLL можно подключать двумя способами:
Статическим — библиотека подключается при запуске программы. Если библиотека или имя функции не найдено, то программа выдаст ошибку и не запустится.
Динамическим — библиотека подключается или непосредственно перед вызовом функции или по определенному событию.

Рассмотрим статический способ подключения:

Type TfmMain = class(TForm) MainMenu: TMainMenu; miProgram: TMenuItem; miExit: TMenuItem; miHelp: TMenuItem; procedure FormCreate(Sender: TObject); procedure miExitClick(Sender: TObject); private public end; procedure PlugIn(Form: TForm); stdcall; external "SampleDLL.dll"; var ...

Ключевое слово external указывает на то, что данная функция подключается из внешней библиотеки.

На событие onCreate формы добавим вызов процедуры PlugIn :

Procedure TfmMain.FormCreate(Sender: TObject); begin PlugIn(Self); end;

В качестве параметра Form передаем в процедуру текущую форму (ключевое слово Self ).

При запуске программы у нас должен появится пункт «О программе» в разделе «Помощь» главного меню.

Переходим к динамическому способу подключения.

Нам понадобятся три функции WinApi :

LoadLibrary
Загружает библиотеку в память компьютера. В качестве результата возвращает указатель на библиотеку в памяти. В случае ошибки вернет 0.

LoadLibrary(lpLibFileName: LPCWSTR): HMODULE;

lpLibFileName — Имя файла библиотеки.

GetProcAddress
Найти функцию в библиотеки по имени. Результатом будет указатель на функцию. Если функция не найдена, то вернет nil .

GetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC;

hModule
lpProcName — Имя функции.

FreeLibrary
Выгружает библиотеку из памяти компьютера. Результатом будет True в случае успешного выполнения и False в случае ошибки.

FreeLibrary(hLibModule: HMODULE): BOOL;

hLibModule — Указатель на загруженную библиотеку.

Теперь с помощью динамического способа получим ресурсы, нашу иконку и на кнопку «Выход» добавим вызов функции YesNoDlg для подтверждения закрытия программы.
На то же событие onCreate добавляем код:

Procedure TfmMain.FormCreate(Sender: TObject); var DLLHandle: THandle; begin PlugIn(Self); DLLHandle:= LoadLibrary("SampleDLL.dll"); if DLLHandle = 0 then raise Exception.Create("Не удалось подключить библиотеку "SampleDLL"!"); try Self.Icon.LoadFromResourceName(DLLHandle, "my_icon"); finally FreeLibrary(DLLHandle); end; end;

И на событие onClick пункта меню «Выход»:

Procedure TfmMain.miExitClick(Sender: TObject); var DLLHandle: THandle; Dlg: function(const Question: PChar): boolean; stdcall; begin DLLHandle:= LoadLibrary("SampleDLL.dll"); if DLLHandle = 0 then raise Exception.Create("Не удалось подключить библиотеку "SampleDLL"!"); try @Dlg:= GetProcAddress(DLLHandle, "YesNoDlg"); if not Assigned(@Dlg) then raise Exception.Create("Функция с именем "YesNoDlg" не найдена в библиотеке "SampleDLL"!"); if Dlg("Выйти из программы?") then Close; finally FreeLibrary(DLLHandle); end; end;

Если вы все написали верно, то после запуска программы должна поменяться иконка формы, добавиться кнопка «О программе», при нажатии на которую будет показывать форма About и на нажатие кнопки выход программа будет запрашивать подтверждение: «Выйти из программы?».

Надеюсь вам будет полезен этот небольшой пример использования возможностей DLL библиотек.
Исходники проекта можно скачать .

DLL-библиотека позволяет объединить в одно целое повторно используемый код. Функции из DLL - библиотеки могут подключаться динамически во время выполнения, в отличие от функций из пакетов Delphi, линкуемых статически на этапе компиляции приложения.

Для того чтобы создать DLL-библиотеку, для начало необходимо выполнить команду меню File|New|Other и выбрать на странице New диалога New Item элемент DLL Wizard.

Мастер DLL Wizard автоматически создаст пустой шаблон для DLL-библиотеки. В отличие от обычного модуля, начинающегося с ключевого слова unit, модуль DLL-библиотеки начинается с ключевого слова library. Секция uses модуля DLL-библиотеки требует подключения только двух пакетов: SysUtils и Classes.

Создание DLL-функции состоит из нескольких этапов:

1. Сначала в секции реализации модуля следует ввести сигнатуру функции и запрограммировать код, выполняемый функцией.

3. В заключение функцию, которую предполагается использовать не только внутри модуля, но и вызывать из других приложений, следует объявить как экспортируемую в секции exports.

Функции из DLL-библиотеки могут вызываться как из приложений, разработанных в Delphi, так и из приложений, написанных на других языках программирования, таких, как C++.

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

Способ передачи параметров указывается через точку с запятой после описания функции. Например:

function F1 (X, Y, Z: Real]: Real; stdcall;.

Различные способы передачи параметров определяют порядок передачи параметров (слева направо или справа налево), а также указывают, кто будет освобождать память стека (вызываемая или вызывающая процедура). При использовании DLL-библиотек в качестве компонентов, вызываемых из приложений на других языках программирования, следует использовать соответствующий модификатор вызова. Для приложений на C++ применяется модификатор вызова stdcall.

Для того чтобы функцию, описанную в DLL-библиотеке, можно было вызвать из другого приложения, эту функцию следует экспортировать. Список всех экспортируемых функций указывается в секции exports через запятую

и завершается символом точка с запятой. Экспорт функций может выполняться тремя способами:

По имени функции, используемому в DLL-библиотеке;

По имени функции, заданному как имя экспорта;

По присвоенному функции индексу.

Для того чтобы присвоить функции некоторый индекс, его следует указать в секции exports после имени функции с ключевым словом index.

Для того чтобы экспортируемая функция вызывалась по имени, отличном от имени, используемого в DLL-библиотеке, в секции exports после имени функции следует указать ключевое слово name и новое имя экспорта для данной функции.

DLL - библиотека не является выполняемым модулем. Для получения ее кода достаточно произвести компиляцию проекта.

library Projectl;

SysUtils, Classes;

function F1(X, Y: Integer): Integer; stdcall;

Статическое подключение DLL-библиотеки

DLL-библиотека может подключаться или статически, или динамически. При подключении DLL-библиотеки она загружается в память приложения.

При статическом подключении DLL-библиотека загружается один раз при запуске приложения. На всем протяжении выполнения приложения имя функции, импортируемой из DLL-библиотеки, которая была подключена статически, указывает на одну и ту же функцию (точку входа в DLL) в одной и той же DLL. Все функции из DLL-библиотеки, которые будут использоваться в приложении первоначально, должны быть объявлены как внешние. При этом следует указать, если требуется, модификатор вызова. Если функция вызывается по индексу, то для нее следует задать имя, используемое в приложении, и индекс функции в DLL-библиотеке.

Объявления внешних функций выполняется в секции implementation до использования этих функций.

Объявление внешней функции с ключевым словом external определяет, что будет использовано статическое связывание.

TForml = class(TForm)

Editl: TEdit; [Поле для ввода первого значения}

Edit2: TEdit; (Поле для ввода второго значения}

Edit3: TEdit; (Поле для отображения результата

выполнения функции из DLL-библиотеки}

Buttonl: TButton; {Выполняется вызов функции, используемой по имени)

Button2: TButton; [Выполняется вызов функции, используемой по индексу}

procedure ButtonlClickfSender: TObject);

procedure Button2Click(Sender: TObject);

{ Private declarations }

(Public declarations }

(Объявление экспортируемых функций}

function Fl (i: Integer; j:Integer): Integer; stdcall;

external "Projectl.dll";

function F2 (i: Integer; j:Integer): Integer; stdcall;

external "Projectl.dll index 2;

procedure TForml.ButtonlClick(Sender: TObject);

{Вызов экспортируемой функции}

Edit3.Text:=IntToStr(Fl(StrToInt(Editl.Text),StrToInt{Edit2.Text)));

procedure TForml.Button2Click(Sender: TObject);

Edit3.Text:=JntToStr(F2(StrToInt(Editl.Text),StrToInt(Edit2.Text)));

Динамическое подключение DLL-библиотеки

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

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

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

1. Создайте новый тип. соответствующий типу вызываемой функции (имя нового типа можно ввести после секции type).

Например:

TMyFl=function(i,j:Integer):Integer; stdcall;

2. В секции var interface-секции модуля создайте переменную созданного типа функции. Например: MyFl: TMyFl;

3. Перед загрузкой DLL-библиотеки объявите переменную типа Integer, которая будет содержать дескриптор подключаемой библиотеки.

4. Вызовите метод LoadLibrary, выполняющий подключение DLL-библиотеки. Например; h:=LoadLibrary ("Projectl.dll");

5. Проверьте, успешно ли выполнено подключение библиотеки. Если имя DLL-библиотеки указано неверно или библиотека не найдена, то функция LoadLibrary вернет значение 0.

6. В случае успешного подключения DLL-библиотеки далее следует получить адрес функции. Для этого используется функция Windows API GetProcAddress, в качестве параметров которой указывается дескриптор DLL-библиотеки и имя подключаемой функции. Например: @MyFl: =GetProcAddress (h, " Fl ");

7. Если адрес функции получен, то значение адреса (в нашем примере @MyFl) не должно быть равно nil.

8. На этом этапе можно выполнять вызов функции из динамически подключенной DLL-библиотеки.

9. Для освобождения и соответственно выгрузки DLL-библиотеки вызовите метод FreeLibrary, выполняющий отключение DLL-библиотеки.

Windows, Messages, SysUtils, Variants, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls;

TForml = class(TForm)

Button3: TButton;

procedure Button3Click

procedure TForml.Button3Click(Sender: TObject);

h:=LoadLibrary("Projectl.dll");

if h <> 0 then

@MyFl:=GetProcAddress(h,"Fl");

if @MyFl <> nil then

Edit3.Text:=IntToStr(MyFl(StrToInt{Editl.Text),

StrToInt(Edit2.Text)));

Использование DLL-библиотеки для вызова общих модальных диалогов.

Результатом выполнения процедуры из DLL-библиотеки может быть отображение некоторого модального диалога. Для этого следует в экспортируемом методе создать объект форма, отобразить ее как модальный диалог, а затем удалить объект форма. При этом в самой форме следует предусмотреть вызов метода Close для завершения диалога.

Для создания формы используется метод Create, в качестве параметра которому передается указатель на родительскую форму - форму вызывающего приложения. Этот параметр передается вызываемой DLL-функции.

library Projectl;

Unitl_DLL in "Unitl_DLL.pas" {Forml};

procedure MyModalForm (var Z:Integer ;F:TForm1); stdcall;

Form1:=TForml.Create(F);

(Параметр F передается при вызове процедуры и содержит указатель

на родительскую форму - форму вызывающего приложения}

Loading...Loading...