Folosind dll ca plugin-uri


Utilizarea DLL-urilor ca PlugIns

Utilizarea DLL-urilor ca PlugIns

În subiectele pentru scrierea articolelor din secțiunea "Hello World", există o întrebare despre bibliotecile dinamice și modulul ShareMem. Aș dori să extind oarecum afirmația întrebării: Să avem nevoie să construim un sistem care să fie funcțional fără dificultate. Soluția evidentă este o bibliotecă de legături dinamice. Și ce fel de apucări sunt împrăștiate pe această cale?

În locul activității mele curente de muncă, problema unui astfel de sistem a apărut cu mult timp în urmă. Și din moment ce nu se va scufunda, era necesar să se creeze un astfel de sistem. Deci toate cele de mai sus sunt de la propria ta experiență.

Utilizarea ShareMem este o chestiune specifică a problemei. Dacă se poate face fără astfel de alocări de memorie, atunci mergeți mai departe, cu piesa! În caz contrar, trebuie să trageți borlndmm.dll împreună cu programul, care pune în aplicare schimburi dureroase de indicii între biblioteci.

Se poate întreba "De ce?". Și obțineți răspunsul "Deci, este necesar!". Se pare că Delphi lucrează cu Heap (o grămadă, din care este alocată memoria) în felul său. Cu ceva timp în urmă, am discutat această problemă, căutăm de-a lungul codurilor sursă și că nu a venit o opinie comună. Dar există o ipoteză că Delphi alocă imediat o bucată mare de memorie în heap și apoi, la cerere, taie piesele necesare din ea, fără a avea încredere în sistem pentru a aloca memorie. Poate că nu este așa și dacă cineva mă corectează, voi fi recunoscător. Oricum - problema există și există o soluție.

Potrivirea proprietăților de nume ale diferitelor ferestre va cauza o excepție. Evitarea acestui lucru nu este dificilă, dar apare o eroare, aparent pentru că diferite tipuri de clase au același nume în același container.

Este foarte important să distrugeți fereastra înainte de a descărca biblioteca și de a termina programul. Delphi se relaxează: pentru resursele dedicate, nu este nevoie să monitorizați, ferestrele în sine sunt create și distruse și multe alte lucruri se fac pentru programator. Înfășurați componentele, stabiliți conexiunea și totul este gata. Imaginați-vă: biblioteca este descărcată, fereastra din bibliotecă există, sistemul din spatele bibliotecii a șters deja descriptorii, dar restul resurselor și ce se întâmplă? Al doilea cinci Delphi atunci când programul este închis se blochează și apoi "Încălcarea accesului". Apoi este tăiat prin cenzură.

Nu mai existau greble. Da, și a menționat - probleme grave nu reprezintă, singurul lucru de care aveți nevoie pentru a scrie cu atenție, textul linge, și chiar gândesc mai des.

Construirea unui program cu plug-in-uri

Poate două abordări pentru construirea unui astfel de program
  • pluginurile obțin informații de la nucleul programului, dar nu se adresează singure kernel-ului. Noi numim această abordare pasivă.
  • Într-o abordare activă, plug-in-urile inițiază anumite evenimente și forțează kernel-ul să le respecte.

A doua abordare necesită o construcție algoritmică mai complexă, așadar o să consider doar prima.

Să avem un program care să poată conecta biblioteci dinamice (oricare). Dar pentru o funcționare eficientă este necesar ca aceste biblioteci să furnizeze o interfață standard pentru transferul de date. În limba rusă, ar trebui să existe un set standard de funcții de bibliotecă exportate prin care programul va comunica cu ei.

În procesul de lucru sa constatat că pentru modelul pasiv 6 funcții sunt suficiente:
  1. Obținerea de informații interne despre plugin (în funcția de program GetModuleInfo: TModuleInfo). Dacă aveți o astfel de funcție în bibliotecă și o numiți corect, vom ști că acest DLL este pluginul nostru. Funcția în sine poate returna orice, de exemplu numele și tipul pluginului.
  2. Formarea valorilor inițiale (în procedura de inițializare a programului). Plugin-ul se pune în ordine după încărcare, adică popula variabilele cu valori implicite.
  3. Transferul de date în plug-in (în procedură de procedură SetData (Kind: TDataKind; const Buffer; Dimensiune: Integer)). Vă permite să transferați date în plugin.
  4. Recuperarea datelor nu este implementată în program, dar se face în tipul SetData.
  5. Rulați plugin-ul (în programul Run). Pluginul este pornit. Acțiunile pot fi diferite: afișarea ferestrelor, afișarea ferestrelor modale, calcularea unor parametri etc.
  6. Și opriți plug-in-ul esesno. Acțiunile respective sunt opusul pasului 2.

Voi vorbi puțin despre transferul de date. Pascal, pentru toată greu de scris, oferă un mijloc plăcut de a transfera la funcția de date netumite. Dacă programul știe exact ce date au venit, ottypirovat :) acestea sunt destul de simple. Această metodă de transmitere este utilizată în SetData. Modulul SharedTypes.Pas utilizat de toate cele trei proiecte descrie constantele corespunzătoare TDataKind pentru tipurile de date transferate.

Acum, despre punerea în aplicare

Lăsați kernelul, adică fișierul exe, caută plug-in-uri, le lansează și le trimite două valori digitale prin timer, pe care un plug-in va reprezenta în formă text, iar al doilea va fi sub formă de diagrame. Implementarea plug-in-urilor este minimă, așa că vă voi spune despre unul - Digital.dll. Să începem enumerarea funcțiilor:

Funcția returnează informații despre modul. În acest caz, acesta este un afișaj digital, calea și tipul modulului.

Procedura memorează variabila aplicație și face o referință nulă la forma pluginului.

Procedura de pornire a pluginului creează o fereastră. Fereastra este creată vizibilă.

Procedura șterge fereastra și returnează vechea aplicație TA.

Procedura de obținere a datelor. În funcție de tipul de date primite, datele din variabila Buffer, respectiv, sunt tipărite. Aici există un apel la forma pluginului, nu îl voi picta, totul este simplu acolo, vedeți codul sursă. Tipurile care sunt utilizate aici sunt descrise în SharedTypes.pas

Acest lucru este valabil pentru plug-in-uri.

După cum puteți vedea din text, acesta este un simplu add-on peste plug-in-ul care nu adaugă funcționalități, dar vă permite să stocați totul într-un singur obiect.

Acum rămâne doar să construim plug-in-urile și să fugăm. Informațiile sunt colectate și lansate făcând clic pe butonul cu același nume din formularul principal. Cum de a construi plugin-uri este o chestiune de gust. În acest exemplu, scanez directorul specificat, îl puteți stoca într-un fișier INI, în registru, puteți veni cu propriul format de stocare. Colecția de pluginuri:

Este recomandabil să nu uitați de eliberarea modulelor. Acest lucru este deja la sfârșit (vezi codul sursă).

Și așa arată.

Folosind dll ca plugin-uri

În acest text, am adus coloana vertebrală a unei posibile soluții pentru construirea unui sistem modular. Întrebări, atacuri și dorințe sunt acceptate.

Maxim Mazitov
Mai ales pentru Regatul Delphi