Bibliotecă de tipări

TLB ( T ype  Library - type library ) este o stocare ierarhică a  informațiilor despre capacitățile serverului ActiveX în OLE Automation .

Biblioteca de tipuri este unul dintre conceptele cheie ale tehnologiei OLE Automation . Biblioteca de tipuri este o stocare ierarhică (pe trei niveluri, numărând elementul rădăcină) de informații despre capacitățile serverului ActiveX . Cel mai adesea, o bibliotecă de tipuri este stocată fie ca fișier separat cu extensia „.tlb” sau „.olb”, fie în interiorul (în resurse ) componenta ActiveX [1] pe care o descrie. În plus, o bibliotecă de tipuri poate locui într- un document compus OLE .

Motive pentru creare

Odată cu apariția tehnologiei ActiveX, a fost nevoie de o singură modalitate recomandată de a obține informații detaliate despre o componentă ActiveX: o listă de clase pe care le implementează și de interfețele suportate , identificatorii acestora, scurte descrieri și multe altele. În acest scop au fost introduse biblioteci de tipuri.

Structura logică

Biblioteca de tipuri este o stocare ierarhică pe trei niveluri: partea de sus a ierarhiei este biblioteca însăși ( ing.  Type Library ), care este un set de descrieri de tip ( ing.  Type Info ), care, la rândul lor, sunt containere de terți. -level elements - members ( ing.  Member ).

Toate cele trei tipuri de elemente au același set de caracteristici de bază:

În plus, bibliotecă și textele dactilografiate au identificatori unici de 128 de biți , în timp ce membrii au identificatori de 32 de biți (unici în cadrul aceluiași dactilografiat). ID-ul bibliotecii se numește LIBID , ID-ul membrului este MEMBERID . Numele identificatorului definiției tipului depinde de tipul definiției tipului.

Biblioteca de tipuri poate descrie opt tipuri diferite de entități. Fiecare descriere de tip definește unul dintre ele. În conformitate cu aceasta, atributul descrierii tipului, care este de o importanță capitală în analiza descrierii tipului, este tipul descrierii tipului ( eng.  Type Kind ). Acest atribut stabilește tipul de entitate descris de dactilografiat dat și, astfel, specifică modul în care toți ceilalți parametri și subelementele dactilografiate vor fi interpretați.

Următorul tabel prezintă tipurile posibile de entități:

Esență Membrii Type Kind numele ID
enumerare _ constante TKIND_ENUM
Unire _ Câmpurile unionale TKIND_UNION
Structură [2] Câmpuri de structură TKIND_RECORD
interfață COM Metode ,
proprietăți ,
câmpuri de clasă ,
evenimente
TKIND_INTERFACE IID (ID interfață)
Interfață Disp [3] TKIND_DISPATCH
Clasa COM Interfețe COM acceptate TKIND_COCLASS CLSID (ClassID)
Poreclă TKIND_ALIAS
modul obișnuit Funcții ,
proprietăți,
variabile
TKIND_MODULE

Înțeles

TLB conține o serie de informații importante necesare atât în ​​timpul dezvoltării, cât și în timpul funcționării aplicațiilor.

Din punct de vedere al informațiilor stocate, biblioteca este un analog [5] mai avansat al fișierelor de antet .

Utilizare

Software

API -ul OLE oferă funcții [6] care vă permit să încărcați și să lucrați cu o bibliotecă de tipuri prin interfețele ITypeLib și ITypeLib2 și cu entitățile stocate în ea prin ITypeInfo și ITypeInfo2.

Limbaje de programare și medii de dezvoltare

Microsoft Visual Basic

Pentru Visual Basic, suportul TLB este natural și integral, deoarece acesta este singurul mecanism care vă permite să aduceți informații despre interfețele, clasele, tipurile existente în spațiul de nume al proiectului: limbajul vă permite să vă declarați propriile interfețe și clase noi, dar cele neexistente [7] . Deci, de exemplu, cele mai multe dintre funcțiile, tipurile, clasele și interfețele „încorporate” ale limbajului sunt declarate în bibliotecile de tipuri corespunzătoare.

Biblioteca de tipuri este conectată la proiect prin Proiect→Referințe (sau indirect prin Proiect→Componente). Mai multe biblioteci „de bază” sunt incluse de la început și nu pot fi dezactivate.

Microsoft Visual C++

MSVC++ este suplimentat cu o directivă specială de preprocesor #import , care creează un spațiu de nume separat pentru biblioteca de tip plug-in [8] , și pentru fiecare entitate descrisă în bibliotecă, o declarație corespunzătoare compatibilă cu C++.

Exemplu:

// Import bibliotecă de tipuri după numele fișierului tlb #import "../tlb/foobar.tlb" // Import bibliotecă de tipuri din resurse de fișiere PE #import "winhttp.dll" // Importați o bibliotecă după LIBID-ul său #import "libid:12341234-1234-1234-1234-123412341234" Borland Delphi și Borland C++ Builder

Aceste medii de dezvoltare au un asistent de import de componente ( ing.  Import Component Wizard ), accesibil prin meniul Component→Import Component, care vă permite să generați fișierul pas- sau h- corespunzător cu declarații bazate pe biblioteca de tipuri.

PHP

PHP are o funcție com_load_typelib() care încarcă o bibliotecă de tipuri și înregistrează constante din acea bibliotecă în spațiul de nume PHP. Funcția com_print_typeinfo() imprimă un dump adaptat al descrierii tipului clasei/interfeței specificate.

Creare

Software

API-ul OLE oferă funcțiile CreateTypeLib, CreateTypeLib2, ICreateTypeLib, ICreateTypeLib2, ICreateTypeInfo, ICreateTypeInfo2, cu care sarcina de a crea și salva o bibliotecă de tip arbitrar este rezolvată programatic. Dezvoltatorii își pot crea propriile aplicații de bibliotecă de tipuri folosind aceste API-uri și interfețe.

Manual

Pentru a dezvolta biblioteci de tipuri, Microsoft a creat un limbaj special MIDL . Fișierele sursă scrise în acest limbaj sunt compilate folosind utilitarul de compilare midl.exe cu același nume . Anterior, mktyplib.exe a fost folosit în aceste scopuri , care acum este considerat învechit și nu este recomandat pentru utilizare. Există o diferență semnificativă între cerințele de intrare ale acestor două utilități: nu orice cod care este corect pentru primul va fi adevărat pentru al doilea și invers [9] .

Un exemplu de declarare a interfeței IShellDispatch în MIDL (din TLB din shell32.dll) [10] [ odl, uuid(D8F015C0 - C278 - 11CE - A49E - 444553540000 ), helpstring( "Definiția interfeței IShellDispatch" ), ascuns, dual, oleautomatizare ] interfață IShellDispatch : IDispatch { [id(0x60020000), propget, helpstring( „Obțineți obiectul aplicației” )] Aplicație HRESULT([out, retval] IDispatch ** ppid); [id(0x60020001), propget, helpstring( „Obțineți obiectul părinte” )] HRESULT Parent([out, retval] IDispatch ** ppid); [id(0x60020002), șir de ajutor ( „Obțineți folderul special de la ShellSpecialFolderConstants” )] HRESULT NameSpace( [în] VARIANT vDir, [out, retval] Folder ** ppsdf); [id(0x60020003), helpstring( „Răsfoiți spațiul de nume pentru un folder” )] HRESULT BrowseForFolder( [în] Hwnd lung , [în] Titlu BSTR, [în] Opțiuni lungi , [în, opțional] VARIANT RootFolder, [out, retval] Folder ** ppsdf); [id(0x60020004), helpstring( „Colecția de ferestre de foldere deschise” )] HRESULT Windows([out, retval] IDispatch ** ppid); [id(0x60020005), șir de ajutor( „Deschide un folder” )] HRESULT Deschide ([în] VARIANT vDir); [id(0x60020006), helpstring( „Explorați un folder” )] HRESULT Explore([în] VARIANT vDir); [id(0x60020007), șir de ajutor( „Minimizează toate ferestrele” )] HRESULT MinimizeAll(); [id(0x60020008), șir de ajutor( „Anulați minimizați totul” )] HRESULTUndoMinimizeALL(); [id(0x60020009), șir de ajutor( „Afișează rularea fișierului” )] HRESULT FileRun(); [id(0x6002000a), șir de ajutor( „Windows în cascadă” )] HRESULT CascadeWindows(); [id(0x6002000b), șir de ajutor( „Telegrați ferestrele pe verticală” )] HRESULT TileVertical(); [id(0x6002000c), șir de ajutor ( „Table ferestre pe orizontală” )] HRESULT TileHorizontal(); [id(0x6002000d), șir de ajutor( „Ieșiți din Windows” )] HRESULT ShutdownWindows(); [id(0x6002000e), șir de ajutor( „Suspenda computerul” )] HRESULT Suspendare(); [id(0x6002000f), șir de ajutor( „Ejectați computerul” )] HRESULT EjectPC(); [id(0x60020010), helpstring( „Afișează dialogul Set time” )] HRESULT SetTime(); [id(0x60020011), helpstring( „Proprietățile tăvii de gestionare” )] HRESULT TrayProperties(); [id(0x60020012), șir de ajutor( „Afișează ajutor shell” )]Ajutor HRESULT (); [id(0x60020013), șir de ajutor( „Găsiți fișiere” )] HRESULT FindFiles(); [id(0x60020014), helpstring( „Găsiți un computer” )] HRESULT FindComputer(); [id(0x60020015), șir de ajutor( „Actualizează meniul” )] HRESULT RefreshMenu(); [id(0x60020016), helpstring( „Runează un element din panoul de control” )] HRESULT ControlPanelItem([in] BSTR szDir);


Extensibilitate

Formatul fișierului bibliotecă de tip oferă posibilitatea extinderii setului de informații stocate în bibliotecă. Pentru stocarea unor informații în bibliotecă, a căror stocare nu a fost inițial intenționată, este posibilă furnizarea oricărui element al ierarhiei (bibliotecă, descriere tip, membru), precum și un parametru de metodă/funcție cu un bloc de date arbitrare ( Date personalizate în engleză  ).

Microsoft nu specifică niciun format pentru un bloc de date arbitrare - poate fi orice date care pot fi stocate într-o variabilă Variant. Cu această abordare, există situații în care diferiți dezvoltatori vor folosi această caracteristică în scopuri diferite, ceea ce ar duce la numeroase probleme de incompatibilitate. Pentru a evita astfel de coliziuni, atunci când salvați și primiți date arbitrare, trebuie să specificați un identificator unic (GUID), care determină în mod unic sensul blocului de date arbitrar și, ca urmare, formatul acestuia.

Astfel, orice element poate fi furnizat nu cu unul, ci cu mai multe blocuri de date arbitrare, iar diferite blocuri pot fi lăsate de programe diferite și servesc unor scopuri complet diferite.

În practică, bibliotecile de tipuri care folosesc această caracteristică sunt extrem de rare.


Diverse

Utilități

Următoarele utilitare pot fi utilizate atunci când lucrați cu biblioteci de tipuri:

  • MIDL (cons.)
    Compilatorul limbajului MIDL, creează un fișier TLB pe baza codului sursă.
  • MkTypLib (cons.) Un
    compilator învechit și depreciat pentru crearea fișierelor TLB. Sintaxa fișierelor de intrare este diferită de cea a MIDL. Dacă trebuie să compilați surse scrise în „stil vechi”, este recomandat să utilizați MIDL cu comutatorul /mktyplib203 [11] .
  • regtlib (cons.) Un
    utilitar pentru înregistrarea bibliotecilor de tipuri în registry .
  • regsvr32 (windows) Un
    utilitar pentru înregistrarea serverelor ActiveX în registru. La înregistrare, TLB stocat în resursele serverului ActiveX este de obicei înregistrat și indirect.
  • Microsoft OLE View (fereastră) Un
    utilitar care afișează o listă cu toate bibliotecile de tip înregistrate în sistem, permițându-vă să vizualizați și conținutul oricăreia dintre ele. Capabil să restaureze codul sursă al elementului vizualizat (al întregii biblioteci/dactilografiate/membru). Livrat cu Microsoft Visual Studio 6.0 .
  • Browserul de obiecte din Visual Basic nu este altceva decât un browser pentru biblioteci de tipuri conectate la un proiect . 

Folosire greșită

Când se dezvoltă în mediul Visual Basic, bibliotecile de tipuri sunt adesea folosite nu pentru scopul propus, ci pentru importul timpuriu [12] al funcțiilor WinAPI obișnuite [13] , ca singura opțiune de import posibilă în VB prin tabelul de import.

Fragment din codul sursă al bibliotecii folosit pentru a importa unele funcții WinAPI ... typedef struct tagCOMBOBOXEXITEMA { mască ComboBoxExItemMaskFlags; int iItem; intpszText; int cchTextMax; int iImagine ; int iSelectedImage; int iOverlay; int iIndent; LPARAM lParam; } COMBOBOXEXITEMA, * PCOMBOBOXEXITEMA; [dllname( "comctl32.dll" )] moduleComCtl { [entry( "InitCommonControlsEx" )] int InitCommonControlsEx(LPINITCOMMONCONTROLSEX lpInitCtrls); [entry( "ImageList_ReplaceIcon" )] int ImageList_ReplaceIcon(HIMAGELIST himl, int i, HICON hicon); } [dllname( "user32.dll" )] modul IconsAPI { [intrare( „ÎncărcareImagineW” )] int LoadImage(int hinst, void * lpszName, int uType, int cxDesired, int cyDesired, int fuLoad); } ...

Note

  1. Care, la rândul său, este un fișier PE și are extensia „.dll”, „.ocx”, „.cpl”, „.exe”, etc.
  2. Conform terminologiei C / C++  - structură (struct), conform terminologiei Pascal  - înregistrare (record), conform terminologiei Visual Basic - tip definit de utilizator (User-Defined Type, UDT).
  3. ↑ O interfață COM derivată din IDispatch care oferă suport pentru legarea tardivă folosind IDispatch::Invoke.
  4. Încărcarea se face de OLE Automation, nu de dezvoltator.
  5. Deoarece stochează informații mult mai utile, este mai compact și mai rapid (nu este nevoie să analizați) fișierele antet și, cel mai important, poate fi folosit în orice mediu de dezvoltare și orice limbaj de programare pe care COM îl acceptă, și nu doar în C/ C++.
  6. LoadTypeLib Arhivat la 21 iulie 2009 la Wayback Machine și LoadTypeLibEx Arhivat la 4 februarie 2011 la Wayback Machine
  7. Limitarea este imposibilitatea de a specifica IID/CLSID pentru interfața/clasa declarată - identificatorul este atribuit automat, ceea ce face ca entitățile declarate să fie fundamental incompatibile cu cele existente.
  8. Acest comportament este dezactivat de modificatorul no_namespace . Consultați MSDN pentru detalii Arhivat 11 februarie 2010 la Wayback Machine
  9. Diferențele între MIDL și MkTypLib Arhivat 27 mai 2010 la Wayback Machine (MSDN).
  10. Codul a fost obținut ca urmare a decompilării TLB de către utilitarul Microsoft OLE/COM Object Viewer.
  11. Key Description /mktyplib203 Arhivat 19 iunie 2010 la Wayback Machine (MSDN).
  12. Spre deosebire de cel de mai târziu, cu ajutorul Declare Sub/Function.
  13. În general, nu au nicio legătură cu COM și, mai mult, cu OLE Automation.