Dll – Dynamic link library – библиотека для основной программы. Помогает разгрузить код основной программы и дать возможность другим программистам пользоваться её методами. Различают статическую и динамическую DLL.
Статическая DLL – загружается в память вместе с программой. Динамическая – загружается только тогда, когда нужен тот или иной метод.
Для небольших приложений, на мой взгляд, уместно использовать статические DLL, а для приложений, сильно расходующих память – динамические.
Как создать DLL?
File | New | Other и выбираем Dynamic-link Library
Далее… в созданном проекте пишем…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
library DLL_Project; { 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 System.SysUtils, System.Classes; {$R *.res} function HelloFromDLL:string; begin Result:='HelloFromDLL'; end; exports HelloFromDLL; begin end. |
Большую часть этого модуля напишет система. Наше дело – добавить функции, которые нам необходимы.
Внимание!!! Build, а не Complile
При создании DLL из проекта нажимать не на Compile, а на Build (Project | Build)
Как можно улучшить статическую загрузку?
Можно использовать директиву Delayed и тогда библиотека загрузится не сразу, а только при использовании одной из функций библиотеки в первый раз.
1 |
function HelloFromDLL:string; external 'dll_project.dll' delayed; |
Как вызвать DLL статически?
Cоздаем обычное приложение VCL. Привожу полный текст модуля
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
unit uMain; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm = class(TForm) Button: TButton; procedure ButtonClick(Sender: TObject); end; var Form: TForm; implementation function HelloFromDLL:string; external 'dll_project.dll'; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin showmessage(HelloFromDLL); end; end. |
Что нужно, чтобы все заработало?
-При создании DLL из проекта нажимать не на Compile, а на Build (Project | Build)
-Название функции в главной программе должно в точности до регистра совпадать с названием функции в DLL. То есть если в нашем примере написать
1 |
function helloFromDLL:string; external 'dll_project.dll'; |
вместо
1 |
function HelloFromDLL:string; external 'dll_project.dll'; |
то работать не будет
Как вызвать метод из DLL динамически?
Привожу полный код. Сначала описываем функцию…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Function Call_HelloFromDLL:string; var h:longint; HelloFromDLL:function:string; {Если метод с параметрами, тогда, например так HelloFromDLL:function (x,y:integer):string;} begin Result:=''; h:=loadlibrary('dll_project.dll'); //Загрузка try if h>0 then begin @HelloFromDLL:=GetProcAddress(h,'HelloFromDLL'); if Assigned(@Call_HelloFromDLL) then Result:=HelloFromDLL; //Собственно использование end; finally Freelibrary(h); //Выгрузка end; end; |
Где размещать DLL?
-В принципе хоть где) Но если Вы хотите, чтобы Windows нашла DLL автоматически, то вот возможные варианты
-В каталоге из которого запускается программа
-В каталоге Windows
-В системном каталоге Windows
-В каталогах, включенных в переменную окружения PATH