Bibliotecă de legături dinamice

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare
Notă despre dezambiguizare.svg Dezambiguizare - "DLL" se referă aici. Dacă sunteți în căutarea altor semnificații, consultați DLL (dezambiguizare) .

O bibliotecă cu legături dinamice (din engleză , tradusă în italiană cu bibliotecă cu legături dinamice ), în informatică , indică o bibliotecă software care este încărcată dinamic în timp de execuție, în loc să fie legată static de un executabil în timpul compilării . Aceste biblioteci sunt cunoscute cu acronimul DLL , care este extensia fișierului pe care îl au în sistemul de operare Microsoft Windows sau, de asemenea, cu termenul biblioteci partajate (din bibliotecă partajată , utilizat în literatura de sisteme Unix ). Pe sistemele care utilizează ELF ca format de fișier executabil , cum ar fiSolaris sau Linux , acestea sunt cunoscute și sub denumirea de „.so”, prescurtare pentru Shared Object .

Avantaje și dezavantaje

Separarea codului în biblioteci de legături dinamice vă permite să împărțiți codul executabil în părți conceptuale separate, care vor fi încărcate numai dacă sunt efectiv necesare. Mai mult, o singură bibliotecă, încărcată în memorie, poate fi utilizată de mai multe programe, fără a fi necesară reîncărcarea, ceea ce economisește resursele sistemului. Această metodă de încărcare la cerere permite, de asemenea, instalarea parțială a unui sistem software, în care doar bibliotecile asociate cu funcțiile pe care utilizatorul dorește să le utilizeze, așa cum sunt selectate în timpul fazei de instalare, sunt de fapt prezente pe memoria de masă.

Un alt avantaj este posibilitatea de a actualiza un program modificând doar DLL-urile: prin inserarea unei versiuni diferite a DLL, care conține, de exemplu, remedieri de erori , toate programele care îl utilizează vor fi automat „actualizate” fără a fi nevoie să fie recompilate.

Principalul dezavantaj este legat de faptul că o nouă versiune a unui DLL ar putea face așa-numitele modificări de rupere , fie în mod voluntar, fie, fără să știe, din cauza bug-urilor din noua versiune. O schimbare de rupere este o schimbare critică în comportamentul codului funcției care îl face să nu mai fie compatibil cu convențiile utilizate (de exemplu, o funcție care a returnat anterior NULL în cazul unei erori în parametri și care acum setează errno și returnează o valoare care nu este nulă). Și mai critic este cazul în care un program de instalare suprascrie un DLL cu o versiune mai veche. Alte probleme pot apărea în mediul COM . Aceste probleme, bine cunoscute programatorilor Windows , sunt grupate sub numele de Hell DLL (DLL Hell).

În unele sisteme de operare, de obicei Unix și Unix-like , este posibil să coexiste versiuni diferite, incompatibile ale aceleiași biblioteci, cu condiția să fie prezente individual pe sistemul de fișiere pe căi diferite și este posibil, atunci când conectați programul, „identificarea versiunii corecte a bibliotecii de utilizat. În acest fel, programele legate înainte de instalarea noii biblioteci pot continua să utilizeze versiunea veche. [1]

Sistemele de operare de tip Windows păstrează o copie de rezervă a DLL-urilor de sistem într-o memorie cache specială, în folderul ascuns C:\windows\system32\dllcache . Bibliotecile utilizate sunt stocate în C:\windows\system32\dll .

DLL-uri în Microsoft Windows

Structura și funcția

Următoarele descriu structura și funcționarea unei biblioteci de legături dinamice într-un mediu Windows, totuși conceptele exprimate sunt în general echivalente în toate sistemele care permit utilizarea bibliotecilor dinamice.

O bibliotecă de legături dinamice este efectiv un cod executabil. Fiecare fișier executabil (EXE sau DLL) are un punct de intrare (punct de intrare) invocat de sistemul de operare imediat după încărcare. Pentru un DLL, punctul de intrare este mapat în mod convențional la funcția DllMain (la discreția compilatorului ).

Funcția DllMain , pe lângă încărcarea DLL, este invocată și la descărcare sau atunci când un fir este creat sau distrus în procesul în care se află DLL.

Spre deosebire de un fișier EXE, DLL trebuie să părăsească punctul de intrare imediat ce a finalizat inițializările necesare.

Structura

Pentru a simplifica, o bibliotecă poate fi gândită ca o colecție de funcții. Fiecare dintre aceste funcții va avea propria adresă de bază, calculată ca un offset față de adresa de bază atribuită de sistemul de operare la încărcarea bibliotecii (vezi paragraful următor). Ceea ce distinge o bibliotecă dinamică este că aceste funcții pot fi exportate , adică numele lor sunt plasate într-o listă într-o secțiune a executabilului. Prin urmare, este posibil să se determine punctul de intrare al unei funcții cu o căutare text pe baza numelui funcției. Această operațiune este realizată de API GetProcAddress care returnează adresa funcției al cărei nume este transmis ca parametru.

Se încarcă

Bibliotecile dinamice sunt încărcate de sistemul de operare în spațiul de memorie al procesului care le-a solicitat. În acest fel, accesarea codului DLL va avea o performanță aproape echivalentă cu cea a codului aplicației în sine sau a codului bibliotecilor statice (vom vedea de ce sunt aproape echivalente mai târziu).

Pentru a împiedica codul aplicației și codul DLL să ocupe aceeași locație de memorie, linkerul va trebui să pregătească DLL pentru relocare . În practică, sistemul de operare determină o zonă de memorie disponibilă și remapează orice referințe de memorie conținute în codul DLL. Deoarece acest lucru necesită timp, fiecare DLL are propria adresă de bază ideală: relocarea va fi necesară numai dacă o DLL anterioară a fost deja mapată la această adresă predeterminată. Pentru a specifica adresa ideală, puteți utiliza o regulă generală, bazată pe litera inițială a numelui DLL, conform tabelului următor:

Scrisoarea inițială Adresa de bază
B.C 0x60000000
DF 0x61000000
GI 0x62000000
JL 0x63000000
MO 0x64000000
relatii cu publicul 0x65000000
PE 0x66000000
VX 0x67000000
YZ 0x68000000

Link către un executabil

Conexiunea unui executabil la o bibliotecă dinamică are loc în timpul execuției (în timpul rulării ) și are loc prin intermediul LoadLibrary API, care acceptă numele bibliotecii ca intrare . De exemplu, LoadLibrary(_T("MyLib.dll")) va încărca DLL MyLib.dll spațiul de memorie al aplicației.

Legătura poate fi de două tipuri: explicită sau implicită.

Link explicit

Conexiunea explicită este gestionată direct de codul programului cu ajutorul celor două API LoadLibrary și GetProcAddress descrise anterior. Dacă utilizați limbajul C , veți aloca un pointer funcției specificate în care, atunci când utilizați funcția solicitată, veți încărca adresa cu GetProcAddress . Această tehnică vă permite să gestionați corect starea în care o DLL necesară nu este prezentă în sistem, dar, în general, este mai greoaie, deoarece necesită utilizarea explicită a celor două API-uri. Această tehnică este esențială atunci când se utilizează unele limbaje de programare, cum ar fi Visual Basic, de exemplu.

Link implicit

Legătura implicită este gestionată direct de linker la momentul compilării și este utilizată atunci când se presupune că o DLL este întotdeauna prezentă pe sistem. Ori de câte ori o funcție conținută într-un DLL este apelată în codul sursă, linkerul va lega apelul de funcție la o funcție stub , adică la o funcție fictivă. În interiorul executabilului va exista un tabel care conține butoanele pentru toate funcțiile DLL necesare. La încărcarea executabilului, sistemul de operare va încărca automat toate DLL-urile necesare și va mapa fiecare stub la punctul de intrare al funcției relative în DLL-ul relativ. Dacă nu este găsită o DLL necesară (sau chiar o singură funcție într-o DLL), sistemul de operare va bloca programul să înceapă cu un mesaj de eroare.

Utilizarea legăturii implicite are un dezavantaj în ceea ce privește performanța, deoarece de fiecare dată când este apelată o funcție conținută într-un DLL, există o dublă săritură pentru a funcționa: mai întâi către stub și apoi la adresa funcției; cheltuielile generale generate sunt de fapt neglijabile.

Conectarea implicită a fost întârziată

O variantă de legătură implicită așteptată de unii compilatori este legarea întârziată . În acest caz, se utilizează un stub special, care nu este mapat la încărcare de către sistemul de operare. În schimb, acest stub , prima dată când este invocat, se va mapa automat (cu tehnica de legătură explicită) la funcția DLL. Această tehnică are avantajul că nu necesită prezența DLL pentru a încărca executabilul, împreună cu comoditatea de a nu fi nevoie să încărcați în mod explicit biblioteca din cod.

Notă

Elemente conexe

linkuri externe

Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT