Pisanie i obsługa bibliotek DLL Drukuj Email
Ocena użytkowników: / 0
SłabyŚwietny 
Wpisany przez Berl   
środa, 07 września 2005 15:19

Jak ogólnie wiadomo, DLL to skrót od Dynamic Link Library. Biblioteka DLL jest plikiem, w którym przechowywany jest skompilowany kod źródłowy, który możemy wykorzystac z poziomu innej aplikacji. Biblioteki DLL stosuje się między innymi po to, aby dużą aplikację rozbić na części. W ten sposób możemy uzyskać mały plik wykonywalny EXE, a procedury będą umieszczone wewnątrz bibliotek DLL, która będzie dynamicznie ładowana do pamięci w razie potrzeby, a potrzebna nam funkcja będzie z niej importowana. Zmniejsza to znacznie zużycie pamięci przez program. Biblioteki DLL są również przydatne przy unowocześnianiu i modyfikowaniu programu - jeśli korzystasz z bibliotek DLL, to nie musisz zmieniać całego programu - wystarczy, że zmienisz i skompilujesz samą bibliotekę DLL. Jedną z ważniejszych zalet bibliotek jest to, że biblioteki napisane w jednym języku programowania da się wykorzystywać z poziomu zupełnie innego języka. Jeśli mamy bibliotekę napisaną w C++, to możemy wykorzystać procedury w niej zawarte także z poziomu Delphi.

 

Na początku musimy sobie taką bibliotekę napisać. Wybieramy więc File/New, a następnie klikamy na DLL Library. Pojawi się okno, w którym będzie kod szkieletu biblioteki DLL. Powinno to wyglądać mniej więcej tak :

procedure Procedura(argument : string); stdcall;
begin
     ShowMessage('Wpisałeś : ' + argument);
end;
 

Należy pamiętać, że procedura ShowMessage pochodzi z modułu Dialogs, więc moduł ten należy dodać do sekcji uses.

Słowo stdcall pojawiające się po nazwie procedury jest dyrektywą, jak ma być wywoływana procedura. istnieją cztery podstawowe dyrektywy :

stdcall - dyrektywa ta zapewnia kompatybilność, jeżeli biblioteka i wykorzystujący ją program są napisane w innych językach programowania;
safecall - dyrektywa ta oznacza, że każdy wyjątek w działaniu procedury zostanie przekazany programowi, który wykorzystuje tą bibliotekę;
register - jest to dyrektywa domyślna. Według programistów z Borlanda zapewnia ona największą efektywność działania;
pascal, cdecl - dyrektywy te zapewniają kompatybilność z wybranym językiem programowania - pascal lub c;

Należy teraz podać jakąś informację dla zewnętrznego programu, wykorzystującego naszą bibliotekę, jakie procedury są w niej zawarte. Nazywa się to eksportowaniem procedury. Po prostu po słowie exports wypisujemy nazwy eksportowanych procedur :

exports Procedura name 'ProceduraWypisujacaArgument';

Ostatnim sposobem eksportowania procedury jest eksportowanie przez indeks. Eksportowanie przez indeks wygląda tak :

exports Procedura index 1;

Kod całej biblioteki będzie wyglądał tak :

library biblioteka;
   uses   Windows, Dialogs;
 
procedure Procedura(argument : string); stdcall;
begin
     ShowMessage('Wpisałeś : ' + argument);
end;
 
exports     Procedura;
begin
end.
 

Zapisujemy naszą bibliotekę pod nazwą biblioteka.dpr, i kompilujemy. W folderze, gdzie ją zapisaliśmy, powinien pojawić się plik Biblioteka.dll.

Zajmijmy się teraz napisaniem programu, który wykorzysta procedurę zawartą w naszej bibliotece DLL. Wybieramy File/New Application, następnie na formie umieszczamy pole TEdit oraz jeden przycisk (TButton). Nastepnie zapisujemy naszą aplikację w tym samym folderze co bibliotekę DLL, nazywając ją Tester, a okno plik z oknem programu nazywając TesterFrm.pas. W Oknie edycji powinien pojawić się taki kod :

unit testerfrm;
   interface
   uses   Windows, Messages, SysUtils, Classes, Graphics,
        Controls, Forms, Dialogs,   StdCtrls;
   type   TForm1 = class(TForm)
     Edit1: TEdit;
     Button1: TButton;
   private
     { Private declarations }
   public
     { Public declarations }
   end;
   var   Form1: TForm1;
   implementation
   {$R *.DFM}
   end.

Teraz musimy wskazać programowi, z jakiej biblioteki ma pobrać procedurę, i jaka to ma być procedura. Nazywa się to importowaniem procedury z biblioteki DLL. Wygląda to mniej więcej tak :

procedure Procedura(argument : string); stdcall 
              external 'biblioteka.dll' index 1;
 

Przedstawiony sposób ładowania biblioteki DLL jest sposobem łatwym, lecz posiadającym wadę, mianowicie biblioteka dll jest ładowana do pamięci od razu przy starcie programu. O wiele bardziej efektywnym sposobem jest dynamiczne ładowanie biblioteki DLL do pamięci. Kod ładujący bibliotekę oraz funkcję do pamięci, wykonujący funkcję oraz zwalniający pamięć wygląda tak :

var   DLL : THandle;
Procedura : procedure(argument : string); stdcall;
begin
   DLL := LoadLibrary('biblioteka.dll');
   try
     @Procedura := GetProcAddress(DLL, 'Procedura');
     if @Procedura = nil then
         raise Exception.Create('Nie ma takiej '+
              'procedury w bibliotece.');
     Procedura(Edit1.Text);
   finally
     FreeLibrary(DLL);
   end;
end;

Funkcja LoadLibrary Zwraca uchwyt do biblioteki DLL, można powiedzieć, że za pomocą tej funkcji ładujemy bibliotekę DLL do pamięci, podobnie jak funkcja GetProcAddress, która ładuje do pamięci konkretną procedurę. FreeLibrary zwalnia pamięć, użytą przez bibliotekę DLL. Kod ten należy umieścić w zdarzeniu OnClick Buttona. Cały kod programu testującego do naszej biblioteki DLL wygląda tak :

unit testerfrm;
   interface
   uses   Windows, Messages, SysUtils, Classes,
           Graphics, Controls, Forms, Dialogs,   StdCtrls;
   type   TForm1 = class(TForm) 
    Edit1: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
     { Private declarations }
   public
     { Public declarations }
   end;
var
   Form1: TForm1;
   implementation
   {$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var 
    DLL : THandle;
    Procedura : procedure(argument : string); stdcall;
begin
     DLL := LoadLibrary('biblioteka.dll');
     try
         @Procedura := GetProcAddress(DLL, 'Procedura');
         if @Procedura = nil then
             raise Exception.Create('Nie ma takiej '+
                 'procedury w bibliotece.');
         Procedura(Edit1.Text);
     finally
         FreeLibrary(DLL);
     end;
end;
end.

I teraz po naciśnięciu przycisku na formie, procedura zawarta w bibliotece DLL wypisze nam tekst wpisany w polu TEdit.

 

Statystyka

Użytkowników : 99
Artykułów : 76
Odsłon : 99786

Gościmy

Naszą witrynę przegląda teraz 2 gości 

Chmura tagów

delphi MySQL dziesiętny WHERE SendMessage Delphi rot-13 cezara binarny system forma WM_SYSCOMMAND ReleaseCapture SET windows szyfrowanie zamiana liczb FROM edytor zmienne