Cât de repede (pentru mine) este timpul - aici suntem și pe pragul IUnknown. Cât de încet (pentru tine) trece timpul - am ajuns doar la pragul lui IUnknown. Dar, totuși, aici suntem pe punctul de a fi "serios COM".
Deci - interfața IUnknown este interfața principală pe care este construită COM. Trebuie să implementeze orice obiect COM, trebuie să fie prezent în orice interfață expusă de obiect. Dar IUnknown este o interfață foarte specială, dacă nu vrei să spui vizibilitatea ei de la client, ci implementarea sa în interiorul obiectului serverului. Și principalele trăsături ale lui IUnknown pe care le vom lua în considerare în acest articol.
Este mai bine să începeți să cunoașteți specificația exactă. Specificația specifică a interfeței IUnknown este conținută în fișierul cu antet C ++ cu numele
Interfața IUnknown are propriul GUID:
De ce sunt necesare metode necunoscute au fost discutate în detaliu înainte. Deci, acum ne gândim doar la modul în care ar trebui implementate aceste metode. Să începem în următoarea ordine.
Metoda AddRef. Conceput pentru a avansa cu un număr de referință. Trebuie să returneze o nouă valoare pentru acest număr de referință - de la 1 la n, dar această valoare poate fi utilizată numai pentru depanare. Microsoft raportează că uneori această valoare poate fi "instabilă". Ce înseamnă "instabil"? Nu știu. Se pare că a însemnat că într-un mediu multifir exact contra valoare cunoscută doar pentru contorul care este protejat împotriva accesului simultan cu mai multe fire dintr-o dată. Dar relevanța valorii actuale a unui contor emis pentru orice fir poate fi imediat distrusă de un fir paralel. De fapt, sensul acestui contor pe partea clientului este într-adevăr disponibil numai atunci când se depanează, nimic altceva nu poate fi construit pe această valoare.
Eliberarea metodelor. Conceput pentru a muta numărul de referință înapoi la unul. Returnează o nouă valoare (după decrementare) a numărului de referință, care poate fi folosită și numai pentru depanare. În acest caz, dacă contorul devine zero, implementarea metodei ar trebui să elibereze resurse, în mod primitiv vorbind - să distrugă obiectul.
Și aici trebuie să fiți atenți - faptul că AddRef și Eliberarea oricărei interfețe sunt deservite de același număr de referință - contorul de referință al întregului obiect. Ie implementarea acestor metode poate fi una pentru întregul obiect.
Dar aici este necesar să ne gândim puțin mai departe. Ce înseamnă cu adevărat expresia: "ar trebui ca metoda să elibereze resurse"? Pentru obiecte simple în proiectare și obiecte tipice, acest lucru, desigur, este echivalent cu eliminarea obiectului însuși obținut de server pentru operațiunea nouă. Dar pentru obiecte complexe, acest lucru nu poate fi adevărat - (. Ele sunt numite rupere-off „rupere-off“), unele interfețe un obiect complex poate pune în aplicare un „separat“, adică nu primiți resurse pentru ele atunci când creați obiectul în sine și primiți resurse numai atunci când cineva solicită o legătură cu această interfață. În acest caz, metodele AddRef și eliberați vor fi obligați să servească pentru două și un număr de referință - totalul pentru întreaga facilitate și private doar pentru interfețe, cum ar fi o parte a obiectului. Și la fel de fracționar ca obiectul a primit resurse, Release le va elibera și le va elibera. În acest caz, prin termenul "resurse" înțeleg nu numai memoria dinamică. De exemplu, o implementare a interfeței poate deschide un fișier, poate stabili o conexiune la rețea și așa mai departe. Aceste resurse ar trebui, de asemenea, să fie eliberate atunci când toate referințele la interfață sunt pierdute.
Pentru unele obiecte (și cât de puțin aveți nevoie și implementați astfel de obiecte?), Similar cu obiectul CBanzai din exemplul # 1. care este un obiect static al nivelului modulului, nu este nevoie de "auto-criminal". Dar numărul de referință pentru un astfel de obiect va trebui să fie menținut de client și pentru un astfel de indicator, AddRef / Release va fi apelat. deși în acest caz nu fac nimic. Principiul trebuie menținut - clientul nu știe cum este implementat obiectul serverului. Clientul cunoaște numai interfața prin care interacționează cu obiectul. Și trebuie să urmez protocolul.
Vedeți - totul este destul de simplu, rațional, rezonabil. De exemplu, eu nu văd (acest lucru este, după cinci ani de utilizare a COM și programe de scris folosindu-l :) nimic de neînțeles - existența unor caracteristici structurale am găsit cauza pe care nu a putut scăpa de - care este motivul pentru care ne-am construit și trebuie să fie puse în aplicare.
De fapt, putem scrie acum al doilea exemplu - exemplul în care obiectele de defecte de proiectare ale primului exemplu va fi corectat mecanismul de software-ul pe care tocmai l-am învățat. Acest lucru va face facilități noastre cu adevărat „obiecte reale COM“, dar, din păcate, nu permit încă să scape de CoCreateInstance emulator - au mici obiecte COM care sunt necesare, care au trăit în „această -Server COM“. Și din "serverul real COM", încă mai știm doar unul dintre cele patru implementate și expuse sistemului de funcții - DllGetClassObject. Prin urmare, chiar după ce am studiat funcționarea exemplului, trecem la următorul subiect - designul serverului COM. Vom amana filosofia pentru o dată ulterioară când vom studia "obiectul real COM".