Delphi lume - biblioteci legate dinamic

Dinamica legată de biblioteci

Bibliotecile dinamice asociate (denumite în continuare DLL-uri) sunt un mecanism universal pentru integrarea în procedurile și funcțiile programului dvs. de către alți programatori și, în general, pe alte limbi de programare decât Object Pascal.

DLL-urile sunt implementate ca module executabile care conțin proceduri, funcții și / sau resurse gata de utilizare. Din punct de vedere al programatorului, există multe în comun între DLL și modulele obișnuite pentru Object Pascal, deoarece în cele din urmă bibliotecile și modulele furnizează subrutine care scutesc programatorul de la scrierea propriului cod. Dar există diferențe fundamentale. Principala este faptul că DLL-urile nu sunt capabile să furnizeze variabile, constante și tipuri în program, deoarece dezvoltatorii DLL pot folosi limbi de programare netipate, de exemplu, limba de asamblare. Ca rezultat, DLL-urile nu pot exporta în program clasele necesare pentru programator astăzi - pachetele sunt utilizate pentru acest lucru.

Dinamica DLL-ului de conexiune le oferă un avantaj important față de module: schimbarea oricărui DLL în majoritatea cazurilor nu necesită recompilarea programului folosind acesta.

Structura textului DLL repetă structura programului obișnuit, cu excepția faptului că secțiunea de instrucțiuni executabile din DLL joacă același rol ca partea de inițiere a modulului: instrucțiunile din această parte sunt executate o singură dată când biblioteca este încărcată în memorie. Fiecare solicitare ulterioară de a încărca o bibliotecă mărește numărul de referință cu unul, dar nu duce la executarea declarațiilor din partea executabilă.

În plus față de numele subrutinei, antetul DLL conține, de asemenea, numărul său de secvență, mai exact indicele întreg atribuit acestuia. Acest lucru permite programului de apelare să nu facă trimitere la nume, ci la indicele subrutinei și, prin urmare, să reducă timpul necesar pentru a stabili o conexiune cu acesta. Indicele este atribuit ordinea de rutină a apariției sale în nomenclatoare: prima rutină din prima listă devine indexul 0, următoarea - 1, etc Programatorul poate schimba indexare silențios și specificați în mod explicit codul subrutină, adăugând numelui ei în indexul listă Exporturile cuvânt și întreaga .. număr nesemnificat în intervalul de la 0 la 32767:

Un programator poate defini numele extern al unui subprogram exportat diferit de numele său real. În acest scop, numele exporturilor și numele extern în apostrofuri sunt adăugate în lista Export:

Programul de asteptare poate indica fie numele subrutinei exportate, fie indexul acesteia. Atunci când este apelat după nume, programul caută nume în tabelul de nume în căutarea celei dorite. Deoarece numele pot consta din seturi de caractere lungi și pot exista mai multe nume în tabel, procesul de căutare a numelui este mai lent decât procesul de căutare index. Prin urmare, programatorii cu experiență preferă să nu facă referire la nume, ci la indicele subrutinei.

Rețineți că, spre deosebire de module, Delphi nu compilează DLL-ul automat în modurile de construire sau construire, deoarece îl tratează pe bună dreptate ca un alt program care nu este asociat la momentul compilării cu programul principal.

Notă: Toate funcțiile DLL-ului nostru utilizează convenția stdcall, care asigură compatibilitatea noilor funcții cu funcțiile API-ului Windows 32. S-ar putea să nu specificăm acest acord; în acest caz, compilatorul ar folosi o convenție de registru mai eficientă, dar referirea la DLL-ul nostru din programele scrise în alte limbi de programare nu ar fi, în general, posibilă.

Dacă ați creat un DLL pentru utilizarea "externă" (în afaraDelphi), declarați subrutinele cu directiva stdcall sau safecall!

Pentru a utiliza subrutine din DLL, trebuie să le descrieți ca externe adăugând numele bibliotecii în apostrofuri după cuvântul extern:

După cum sa menționat deja, subrutina se numește prin nume sau prin index. În exemplul nostru, o subrutină cu numele extern "murgos" este apelată din biblioteca MyDLL. Dacă doriți să vă referiți la indexul unei subrutine, numele bibliotecii este urmat de indexul cuvântului și de index:

În acest caz, numele sub care va fi cunoscută subrutina programului nu poate coincide cu numele DLL extern al acestuia. Cu toate acestea, programatorul poate înlocui în mod explicit numele subrutinei, chiar dacă se referă la numele său extern:

În această variantă, se presupune că procedura este exportată cu numele extern "ExtName".

13.4.1. Încărcarea statică

Următorul program utilizează biblioteca Сmpix descrisă pe pagina anterioară.

Notă: funcția de bibliotecă cmpixAdd are numele extern addc. Această funcție (cu majuscule) descrie această funcție în exemplul de mai sus. Dacă am fi folosit

linkerul nu ar fi capabil să o identifice.

13.4.2. Încărcare dinamică

Metoda de definire a funcțiilor și procedurilor DLL de mai sus (utilizând directiva externă) determină compilatorul să pună o listă a tuturor DLL-urilor în antetul programului, iar încărcătorul va încărca bibliotecile în memorie simultan cu sarcina programului în sine. Programul poate încărca DLL-ul fără cel extern folosind trei

Funcțiile standard. LoadLibrary, GetProcAddress și FreeLibrary.

Următorul exemplu ilustrează tehnica de încărcare a DLL Cmplx:

13.4.3. Modulul de interfață

Un astfel de modul de interfață simplifică foarte mult dezvoltarea programului principal: în exemplul nostru furnizează aceeași interfață cu biblioteca cmpix, ca modulul cmpix descris mai sus pentru obiectele sale.

Atunci când accesați rutine DLL scrise în alte limbi de programare, se poate dovedi că numele extern al subrutinei conține caractere care nu pot fi conținute în identificatorul corect Delphi. De exemplu, limba C ++ permite utilizarea simbolului "@" în identificatori. În acest caz (și, de asemenea, dacă doriți să redenumiți subrutina exportată din DLL), apelați subrutina orice identificator corect din punct de vedere al Delphi și specificați numele real al subrutinei după numele cuvântului. De exemplu:

13.5. INCLUZIUNE ÎN FORMELE BIBLIOGRAFIEI

Următorul exemplu ilustrează tehnica de includere a unui formular într-un DLL și de utilizare a acestuia în programul de apel.

Formați text în DLL

Textul programului de asteptare

Modulul de formular DLLForm, plasat în DLL, se referă la modulul Forms standard și astfel devine obiectul său global de aplicație, care nu cunoaște nimic despre obiectul global al programului apelant (vezi Capitolul 21). În modul de apel modal, acest lucru nu contează cu adevărat, deoarece fereastra modală blochează funcționarea programului apelant. În modul de apel nemodal, sincronizați acțiunile obiectelor, de exemplu, minimizarea ferestrei principale, de exemplu, nu va reduce la minimum fereastra DLL. Sincronizarea se realizează prin faptul că descriptorul obiectului Application DLL este înlocuit cu descriptorul corespunzător al programului apelant.