Komponentowy model obiektowy — Component Object Model

COM
Komponentowy model obiektowy
Status Obowiązujący
Opublikowane po raz pierwszy 1993 ; 28 lat temu ( 1993 )
Ostatnia wersja Standard życia
2021
Organizacja Microsoft
Seria Usługi systemowe
Standardy podstawowe ŚREDNI , UUID
Powiązane standardy
Domena Interfejsy komponentów
Skrót COM
Strona internetowa dokumenty .microsoft .com /en-us /windows /win32 /com /the-component-object-model

Component Object Model ( COM ) to standard interfejsu binarnego dla komponentów oprogramowania wprowadzony przez firmę Microsoft w 1993 roku. Służy do tworzenia obiektów komunikacyjnych między procesami w wielu językach programowania . COM jest podstawą dla kilku innych technologii i frameworków Microsoft, w tym OLE , OLE Automation , Browser Helper Object , ActiveX , COM+ , DCOM , powłoki Windows , DirectX , UMDF i Windows Runtime . Istotą COM jest neutralny językowo sposób implementacji obiektów, które mogą być używane w środowiskach innych niż to, w którym zostały utworzone, nawet poza granicami maszyn. W przypadku dobrze opracowanych komponentów COM umożliwia ponowne użycie obiektów bez wiedzy o ich wewnętrznej implementacji, ponieważ zmusza realizatorów komponentów do zapewnienia dobrze zdefiniowanych interfejsów, które są oddzielone od implementacji. Różne semantyki alokacji języków są uwzględniane przez uczynienie obiektów odpowiedzialnymi za ich własne tworzenie i niszczenie poprzez zliczanie odwołań . Rzutowanie konwersji typu między różnymi interfejsami obiektu odbywa się za pomocą metody. Preferowaną metodą „dziedziczenia” w modelu COM jest tworzenie obiektów podrzędnych, do których „wywołania” metody są delegowane. QueryInterface

COM to technologia interfejsu zdefiniowana i zaimplementowana jako standard tylko w systemie Microsoft Windows i Apple's Core Foundation 1.3 oraz nowszym interfejsie programowania aplikacji (API) typu plug-in . Ten ostatni implementuje tylko podzbiór całego interfejsu COM. W przypadku niektórych aplikacji model COM został zastąpiony przynajmniej w pewnym stopniu przez platformę Microsoft .NET i obsługę usług sieci Web za pośrednictwem programu Windows Communication Foundation (WCF). Jednak obiekty COM mogą być używane we wszystkich językach .NET za pośrednictwem .NET COM Interop . Sieciowy model DCOM używa zastrzeżonych formatów binarnych , podczas gdy WCF zachęca do korzystania z komunikatów protokołu SOAP opartych na języku XML . COM jest bardzo podobny do innych technologii interfejsu oprogramowania komponentowego , takich jak CORBA i Enterprise JavaBeans , chociaż każda z nich ma swoje mocne i słabe strony. W przeciwieństwie do C++, COM zapewnia stabilny interfejs binarny aplikacji (ABI), który nie zmienia się między wydaniami kompilatora. Dzięki temu interfejsy COM są atrakcyjne dla zorientowanych obiektowo bibliotek C++, które mają być używane przez klientów skompilowanych przy użyciu różnych wersji kompilatora.

Historia

Jedną z pierwszych metod komunikacji międzyprocesowej w systemie Windows była dynamiczna wymiana danych (DDE), wprowadzona po raz pierwszy w 1987 roku, która umożliwiała wysyłanie i odbieranie wiadomości w tzw. „rozmowach” między aplikacjami. Antony Williams , który był zaangażowany w tworzenie architektury COM, później rozprowadził w Microsoft dwa dokumenty wewnętrzne, które obejmowały koncepcję komponentów oprogramowania: Architektura obiektowa: Radzenie sobie z nieznanym – lub – Type Safety in a Dynamically Extensible Class Library w 1988 oraz O dziedziczeniu: co to oznacza i jak z niego korzystać w 1990 r. Stanowiły one podstawę wielu pomysłów stojących za COM. Object Linking and Embedding (OLE), pierwszy framework Microsoft oparty na obiektach, został zbudowany na bazie DDE i zaprojektowany specjalnie dla dokumentów złożonych . Został wprowadzony w programie Word dla Windows i Excel w 1991 roku, a później został dołączony do systemu Windows, począwszy od wersji 3.1 w 1992 roku. Przykładem złożonego dokumentu jest arkusz kalkulacyjny osadzony w dokumencie programu Word dla Windows: w miarę wprowadzania zmian w arkuszu kalkulacyjnym w programie Excel pojawiają się automatycznie w dokumencie programu Word.

W 1991 roku firma Microsoft wprowadziła rozszerzenia Visual Basic (VBX) wraz z Visual Basic 1.0. VBX to spakowane rozszerzenie w postaci biblioteki dołączanej dynamicznie (DLL), która umożliwia graficzne umieszczanie obiektów w formularzu i manipulowanie nimi za pomocą właściwości i metod . Zostały one później przystosowane do użytku przez inne języki, takie jak Visual C++ . W 1992 roku, kiedy została wydana wersja 3.1 systemu Windows , firma Microsoft wydała OLE 2 z jego podstawowym modelem obiektowym . COM interfejs binarny aplikacji (ABI) była taka sama jak MAPI ABI (wydany w 1992), a jak to było oparte na MSRPC i ostatecznie na Open Group „s DCE / RPC . Podczas gdy OLE 1 koncentrował się na złożonych dokumentach, COM i OLE 2 zostały zaprojektowane z myślą o ogólnych komponentach oprogramowania. Konwersacje tekstowe i wiadomości systemu Windows okazały się nie być wystarczająco elastyczne, aby umożliwić udostępnianie funkcji aplikacji w solidny i rozszerzalny sposób, więc COM został stworzony jako nowy fundament, a OLE zmieniono na OLE2. W 1994 roku niestandardowe kontrolki OLE (OCX) zostały wprowadzone jako następca kontrolek VBX. W tym samym czasie Microsoft stwierdził, że OLE 2 będzie znane jako „OLE” i że OLE nie jest już akronimem, ale nazwą wszystkich technologii składowych firmy. Na początku 1996 r. firma Microsoft znalazła nowe zastosowanie dla niestandardowych kontrolek OLE, rozszerzając możliwości swojej przeglądarki internetowej w zakresie prezentowania zawartości, zmieniając nazwy niektórych części OLE związanych z Internetem naActiveX ” i stopniowo przemianowując wszystkie technologie OLE na ActiveX, z wyjątkiem technologii dokumentów złożonych. który był używany w Microsoft Office . Później w tym samym roku firma Microsoft rozszerzyła COM do pracy w sieci za pomocą DCOM .

Powiązane technologie

COM był główną platformą programistyczną dla systemu Windows i jako taki wpłynął na rozwój wielu technologii pomocniczych. Podobnie duży wpływ miały na to wcześniejsze technologie.

DDE

COM zastąpił DDE jako preferowaną formę komunikacji międzyprocesowej.

DCE/RPC i MSRPC

Jako wielojęzyczny model komponentów, model COM opiera się na języku definicji interfejsu lub IDL, aby opisać obiekty i związane z nimi funkcje. COM IDL jest oparty w dużej mierze na bogatym w funkcje DCE/RPC IDL, z rozszerzeniami zorientowanymi obiektowo. Własna implementacja DCE/RPC firmy Microsoft, znana jako MSRPC, jest intensywnie wykorzystywana jako główny mechanizm komunikacji między procesami dla usług Windows NT i komponentów wewnętrznych, co czyni ją oczywistym wyborem podstawy.

DCOM

DCOM ( Distributed COM ) rozszerzył zasięg COM, od obsługi pojedynczego użytkownika za pomocą oddzielnych aplikacji komunikujących się na pulpicie systemu Windows do aktywowania obiektów działających w różnych kontekstach bezpieczeństwa i na różnych komputerach w sieci. Dzięki temu dodano niezbędne funkcje umożliwiające konfigurowanie, którzy użytkownicy mają uprawnienia do tworzenia, aktywowania i wywoływania obiektów, identyfikowania użytkownika wywołującego, a także określania wymaganego szyfrowania dla bezpieczeństwa połączeń.

COM+

W celu zapewnienia programistom przez Microsoft wsparcia dla transakcji rozproszonych , łączenia zasobów, odłączonych aplikacji, publikacji i subskrypcji zdarzeń, lepszego zarządzania pamięcią i procesorem (wątkami), a także pozycjonowania systemu Windows jako alternatywy dla innych systemów operacyjnych klasy korporacyjnej, Microsoft wprowadził technologię o nazwie Microsoft Transaction Server (MTS) w systemie Windows NT 4. W systemie Windows 2000 to znaczące rozszerzenie COM zostało włączone do systemu operacyjnego (w przeciwieństwie do serii zewnętrznych narzędzi dostarczanych przez MTS ) i przemianowane na COM+ . Jednocześnie Microsoft nie kładł nacisku na DCOM jako na odrębną jednostkę. Komponenty korzystające z usług COM+ były obsługiwane bardziej bezpośrednio przez dodaną warstwę COM+, w szczególności przez obsługę przechwytywania przez system operacyjny. W pierwszym wydaniu MTS dołączono przechwytywanie — zainstalowanie komponentu MTS zmodyfikowałoby rejestr Windows tak, aby wywoływał oprogramowanie MTS, a nie bezpośrednio. System Windows 2000 zrewidował również aplikację panelu sterowania Component Services używaną do konfigurowania składników COM+.

Zaletą COM+ było to, że można go było uruchomić w „farmach komponentów”. Instancje komponentu, jeśli są poprawnie zakodowane, mogą być gromadzone i ponownie wykorzystywane przez nowe wywołania jego procedury inicjującej bez wyładowywania go z pamięci. Komponenty mogą być również dystrybuowane (wywoływane z innej maszyny). COM+ i Microsoft Visual Studio zapewniły narzędzia ułatwiające generowanie serwerów proxy po stronie klienta, więc chociaż DCOM był używany do wykonywania zdalnego wywołania, programiści mogli to zrobić z łatwością. W modelu COM+ wprowadzono również mechanizm zdarzeń subskrybenta/wydawcy o nazwie Zdarzenia COM+ i udostępniono nowy sposób wykorzystania usługi MSMQ (technologii zapewniającej asynchroniczne przesyłanie wiadomości międzyaplikacyjnych) ze składnikami zwanymi Składnikami w kolejce . Zdarzenia COM+ rozszerzają model programowania COM+ o obsługę zdarzeń z późnym wiązaniem (zobacz Późne wiązanie ) lub wywołań metod między wydawcą lub subskrybentem a systemem zdarzeń.

.INTERNET

Microsoft .NET zapewnia środki zarówno do dostarczania technologii komponentów, jak i do interakcji z COM+ (poprzez zestawy COM-interop); .NET dostarcza otoki dla większości powszechnie używanych kontrolek COM. Microsoft .NET ukrywa większość szczegółów przed tworzeniem komponentów, co ułatwia programowanie. Platforma .NET może korzystać z modelu COM+ za pośrednictwem przestrzeni nazw System.EnterpriseServices, a kilka usług oferowanych przez model COM+ zostało zduplikowanych w ostatnich wydaniach platformy .NET. Na przykład przestrzeń nazw System.Transactions w programie .NET udostępnia klasę TransactionScope, która zapewnia zarządzanie transakcjami bez uciekania się do modelu COM+. Podobnie składniki w kolejce można zastąpić przez Windows Communication Foundation za pomocą transportu MSMQ . (MSMQ jest jednak natywnym składnikiem COM). Obsługa kompatybilności wstecznej jest ograniczona. Obiekt COM może być używany w .NET przez implementację opakowania wywoływanego w czasie wykonywania (RCW). Obiekty NET, które są zgodne z pewnymi ograniczeniami interfejsu, mogą być używane w obiektach COM przez wywołanie wywoływalnego opakowania COM (CCW). Zarówno po stronie COM, jak i .NET obiekty korzystające z innej technologii są wyświetlane jako obiekty natywne. Zobacz COM Interop . WCF (Windows Communication Foundation) ułatwia szereg wyzwań dotyczących zdalnego wykonywania COM. Na przykład pozwala na łatwiejsze uporządkowanie obiektów według wartości przez granice procesów lub maszyn.

Środowisko wykonawcze Windows

Nowy model programowania i aplikacji Microsoft Windows Runtime (lub WinRT, nie mylić z Windows RT ) jest zasadniczo interfejsem API opartym na modelu COM, chociaż opiera się na ulepszonym modelu COM. Ze względu na swoją podstawę zbliżoną do modelu COM, środowisko wykonawcze systemu Windows umożliwia stosunkowo łatwe łączenie się z wieloma językami, tak jak robi to COM, ale zasadniczo jest to niezarządzany, natywny interfejs API. Definicje API są jednak przechowywane w plikach „.winmd”, które są zakodowane w formacie metadanych ECMA 335, tym samym formacie metadanych CLI , którego używa .NET z kilkoma modyfikacjami. Ten typowy format metadanych pozwala na znacznie mniejsze obciążenie niż P/Invoke, gdy WinRT jest wywoływany z aplikacji .NET, a jego składnia jest znacznie prostsza.

Nano-COM (znany również jako XPCOM)

Nano-COM to niezwykle mały podzbiór modelu obiektów składowych, który koncentruje się wyłącznie na aspektach interfejsu binarnego aplikacji (ABI) modelu COM, aby umożliwić wywołania funkcji i metod w niezależnie skompilowanych modułach/komponentach. Nano-COM można łatwo wyrazić w pojedynczym pliku nagłówkowym C++, który można przenosić na wszystkie kompilatory C++. Nano-COM rozszerza natywny ABI podstawowej architektury instrukcji i systemu operacyjnego, dodając obsługę typowanych odwołań do obiektów (typowe ABI skupiają się tylko na atomowych typach, strukturach, tablicach i konwencjach wywoływania funkcji). Podstawa Nano-COM została wykorzystana przez Mozillę do ładowania Firefoksa (nazywanego XPCOM ) i jest obecnie używana jako podstawowa technologia ABI dla DirectX / Direct3D / DirectML .

Plik nagłówkowy Nano-COM definiuje lub nazywa co najmniej trzy typy:

  • GUID do identyfikacji typów interfejsów - jest to faktycznie 128-bitowa liczba
  • HRESULT do identyfikowania kodów błędów z wywołań metod - jest to efektywnie standardowe użycie 32-bitowych int do dobrze znanych wartości (S_OK, E_FAIL, E_OUTOFMEMORY, itp.)
  • IUnknown jako typ bazowy dla wszystkich wpisanych referencji do obiektów - jest to efektywnie abstrakcyjne funkcje wirtualne wspierające dynamic_cast<T>-style pozyskiwanie nowych typów interfejsów i liczenie referencji a lashared_ptr<T>

Wiele zastosowań Nano-COM definiuje również dwie funkcje do adresowania buforów pamięci przydzielonych rozmówcom jako wyniki

  • <NanoCom>Alloc – wywoływane przez implementacje metod w celu alokacji surowych buforów (nie obiektów), które są zwracane do wywołującego
  • <NanoCom>Bezpłatne – wywoływane przez wywołujące metody, aby zwolnić bufory przydzielone do rozmówcy, gdy nie są już używane

Niektóre implementacje Nano-COM, takie jak Direct3D, unikają funkcji alokatora i ograniczają się do używania tylko buforów alokowanych przez rozmówcę.

Nano-COM nie ma pojęcia o klasach, mieszkaniach, porządkowaniu, rejestracji itp. Odniesienia do obiektów są po prostu przekazywane przez granice funkcji i przydzielane za pomocą standardowych konstrukcji językowych (np. nowy operator C++).

Bezpieczeństwo

Komponenty COM i ActiveX są uruchamiane jako kod natywny na komputerze użytkownika, bez piaskownicy. Dlatego istnieje kilka ograniczeń dotyczących tego, co może zrobić kod. Dotychczasowa praktyka osadzania komponentów ActiveX na stronach internetowych z Internet Explorerem prowadziła zatem do problemów z infekcjami malware . Microsoft rozpoznał problem z ActiveX już w 1996 roku, kiedy Charles Fitzgerald powiedział: „Nigdy nie twierdziliśmy z góry, że ActiveX jest wewnętrznie bezpieczny”. Najnowsze wersje programu Internet Explorer monitują użytkownika przed zainstalowaniem formantów ActiveX, umożliwiając użytkownikowi zabronienie instalacji formantów z witryn, którym użytkownik nie ufa. Formantów ActiveX są podpisane z podpisów cyfrowych w celu zapewnienia ich autentyczności. Możliwe jest również całkowite wyłączenie formantów ActiveX lub zezwolenie tylko na kilka wybranych. Przejrzysta obsługa serwerów COM out-of-process nadal promuje bezpieczeństwo oprogramowania pod względem izolacji procesów . Może to być przydatne do rozdzielenia podsystemów o dużych aplikacjach na oddzielne procesy. Izolacja procesów ogranicza uszkodzenie stanu w jednym procesie przed negatywnym wpływem na integralność innych procesów, ponieważ komunikują się one tylko przez ściśle określone interfejsy. W związku z tym, aby przywrócić prawidłowy stan, należy zrestartować tylko ten podsystem. Inaczej jest w przypadku podsystemów w ramach tego samego procesu, gdzie fałszywy wskaźnik w jednym podsystemie może losowo uszkodzić inne podsystemy.

Szczegóły techniczne

Programiści COM budują swoje oprogramowanie przy użyciu komponentów zgodnych z COM . Różne typy składników są identyfikowane przez identyfikatory klas (CLSID), które są globalnie unikalnymi identyfikatorami (GUID). Każdy składnik COM udostępnia swoją funkcjonalność poprzez jeden lub więcej interfejsów . Różne interfejsy obsługiwane przez komponent są odróżniane od siebie za pomocą identyfikatorów interfejsów (IID), które również są identyfikatorami GUID. Interfejsy COM mają powiązania w kilku językach, takich jak C , C++ , Visual Basic , Delphi , Python i kilka języków skryptowych zaimplementowanych na platformie Windows. Cały dostęp do komponentów odbywa się za pomocą metod interfejsów. Pozwala to na zastosowanie technik takich jak programowanie międzyprocesowe, a nawet międzykomputerowe (to ostatnie z wykorzystaniem wsparcia DCOM).

Interfejsy

Wszystkie składniki COM implementują interfejs IUnknown ( custom ), który udostępnia metody zliczania odwołań i konwersji typu (rzutowania). Niestandardowy interfejs IUnknown zawiera wskaźnik do wirtualnej tablicy metod , które zawiera listę wskaźników do funkcji, które realizują funkcje zadeklarowane w interfejsie, w tej samej kolejności, że są one zadeklarowane w interfejsie. Obciążenie wywołania w procesie jest zatem porównywalne z wywołaniami metod wirtualnych w C++ . Oprócz interfejsów niestandardowych model COM obsługuje również interfejsy dyspozytorskie dziedziczące po IDispatch . Interfejsy dyspozytorskie obsługują późne wiązanie dla automatyzacji OLE . Pozwala to na natywny dostęp do interfejsów dyspozytorskich z szerszej gamy języków programowania niż interfejsy niestandardowe .

Klasy

Klasa COM ("koklasa") jest konkretną implementacją jednego lub więcej interfejsów i bardzo przypomina klasy w obiektowych językach programowania . Klasy są tworzone na podstawie ich identyfikatora klasy ( CLSID ) lub na podstawie ich programowego ciągu identyfikatora ( ProgID ). Podobnie jak wiele języków obiektowych, COM zapewnia oddzielenie interfejsu od implementacji. To rozróżnienie jest szczególnie silne w modelu COM, gdzie do obiektów nie można uzyskać dostępu bezpośrednio, a jedynie poprzez ich interfejsy. Model COM obsługuje również wiele implementacji tego samego interfejsu, dzięki czemu klienci w czasie wykonywania mogą wybrać implementację interfejsu do utworzenia.

Biblioteki języków i typów definicji interfejsu

Biblioteki typów zawierają metadane do reprezentowania typów COM. Te typy są opisane przy użyciu języka definicji interfejsu firmy Microsoft (MSIDL/IDL). Pliki IDL definiują klasy obiektowe, interfejsy, struktury, wyliczenia i inne typy zdefiniowane przez użytkownika w sposób niezależny od języka. IDL jest podobny z wyglądu do deklaracji C++ z kilkoma dodatkowymi słowami kluczowymi, takimi jak "interface" i "library" do definiowania interfejsów i kolekcji klas. IDL obsługuje również użycie atrybutów w nawiasach przed deklaracjami w celu dostarczenia dodatkowych informacji, takich jak identyfikatory GUID interfejsu i relacje między parametrami wskaźnika i polami długości. Pliki IDL są kompilowane przez kompilator MIDL . W przypadku języka C/C++ kompilator MIDL generuje niezależny od kompilatora plik nagłówkowy zawierający definicje struktur, aby dopasować vtbls zadeklarowanych interfejsów i plik C zawierający deklaracje identyfikatorów GUID interfejsu . Kod źródłowy C++ dla modułu proxy może być również generowany przez kompilator MIDL. Ten serwer proxy zawiera skróty metod do konwersji wywołań COM na zdalne wywołania procedur, aby umożliwić DCOM komunikację poza procesem. Pliki IDL mogą być również kompilowane przez kompilator MIDL do biblioteki typów (TLB). Pliki TLB zawierają metadane binarne, które mogą być przetwarzane przez różne kompilatory języków i środowiska uruchomieniowe (np. VB, Delphi, .NET itp.) w celu generowania konstrukcji specyficznych dla języka reprezentujących typy COM zdefiniowane w TLB. W przypadku C++ spowoduje to przekonwertowanie TLB z powrotem na jego reprezentację IDL.

Ramy obiektów

Ponieważ COM jest strukturą środowiska uruchomieniowego, typy muszą być indywidualnie identyfikowalne i możliwe do określenia w czasie wykonywania. Aby to osiągnąć, używane są globalnie unikalne identyfikatory (GUID). Każdy typ COM jest wyznaczony własnym identyfikatorem GUID do identyfikacji w czasie wykonywania. Aby informacje o typach COM były dostępne zarówno w czasie kompilacji, jak i w czasie wykonywania, COM używa bibliotek typów. To właśnie dzięki efektywnemu wykorzystaniu bibliotek typów COM osiąga swoje możliwości jako dynamicznej struktury interakcji obiektów.

Rozważ następującą przykładową definicję koklasy w IDL:

coclass SomeClass {
  [default] interface ISomeInterface;
};

Powyższy fragment kodu deklaruje nazwę klasy COM, SomeClassktóra implementuje interfejs o nazwie ISomeInterface.

Jest to koncepcyjnie równoważne zdefiniowaniu następującej klasy C++:

class SomeClass : public ISomeInterface {
  ...
  ...
};

gdzie ISomeInterface jest czystą klasą wirtualną C++ (czasami nazywaną abstrakcyjną klasą bazową).

Pliki IDL zawierające interfejsy i klasy COM są kompilowane w pliki bibliotek typów (TLB), które mogą być później analizowane przez klientów w czasie wykonywania w celu określenia, które interfejsy obsługuje obiekt, i wywołania metod interfejsu obiektu.

W języku C++ obiekty COM są tworzone za pomocą CoCreateInstancefunkcji, która jako argumenty przyjmuje identyfikator klasy (CLSID) i identyfikator interfejsu (IID). Instancję SomeClassmożna zaimplementować w następujący sposób:

ISomeInterface* interface_ptr = NULL;
HRESULT hr = CoCreateInstance(CLSID_SomeClass, NULL, CLSCTX_ALL,
                              IID_ISomeInterface, (void**)&interface_ptr);

W tym przykładzie podsystem COM jest używany do uzyskania wskaźnika do obiektu, który implementuje ISomeInterfaceinterfejs, i wymagana jest szczególna implementacja tego interfejsu w koklasie CLSID_SomeClass.

Liczenie referencji

Wszystkie obiekty COM wykorzystują zliczanie odwołań do zarządzania okresami istnienia obiektów. Liczniki odwołań są kontrolowane przez klientów za pomocą metod AddRef i Release w obowiązkowym interfejsie IUnknown, który implementują wszystkie obiekty COM. Obiekty COM są wtedy odpowiedzialne za zwolnienie własnej pamięci, gdy liczba odwołań spadnie do zera. Niektóre języki (np. Visual Basic ) zapewniają automatyczne zliczanie odwołań, dzięki czemu deweloperzy obiektów COM nie muszą jawnie utrzymywać żadnego wewnętrznego licznika odwołań w swoich kodach źródłowych. W C++ programista może albo wykonać jawne zliczanie odwołań, albo użyć inteligentnych wskaźników do automatycznego zarządzania licznikami odwołań.

Poniżej znajdują się wskazówki, kiedy należy wywoływać AddRef i Release na obiektach COM:

  • Funkcje i metody, które zwracają referencje interfejsu (poprzez wartość zwracaną lub przez parametr "out"), zwiększają liczbę odwołań zwracanego obiektu przed zwróceniem.
  • Release musi zostać wywołane na wskaźniku interfejsu, zanim wskaźnik zostanie nadpisany lub wyjdzie poza zakres.
  • Jeśli kopia jest tworzona na wskaźniku odwołania do interfejsu, AddRef powinien zostać wywołany na tym wskaźniku.
  • AddRef i Release muszą być wywołane na określonym interfejsie, do którego się odwołuje, ponieważ obiekt może implementować liczniki odwołań na interfejs w celu alokacji zasobów wewnętrznych tylko dla interfejsów, do których się odwołuje.

Nie wszystkie wywołania licznika odwołań są wysyłane do obiektów zdalnych przez sieć; proxy przechowuje tylko jedno odwołanie do zdalnego obiektu i utrzymuje własną lokalną liczbę odwołań. Aby uprościć opracowywanie COM, firma Microsoft wprowadziła ATL (Active Template Library) dla programistów C++. ATL przewiduje paradygmat rozwoju COM wyższego poziomu. Chroni również programistów aplikacji klienckich COM przed koniecznością bezpośredniego utrzymywania zliczania odwołań, udostępniając obiekty inteligentnych wskaźników . Inne biblioteki i języki zgodne z modelem COM obejmują Microsoft Foundation Classes , VC Compiler COM Support , VBScript , Visual Basic , ECMAScript ( JavaScript ) i Borland Delphi .

Programowanie

COM jest język agnostyk binarny standard, który może być realizowana w dowolnym języku programowania zdolny do zrozumienia i realizacji swoich typów danych binarnych zdefiniowane i interfejsy. Implementacje COM odpowiadają za wchodzenie i wychodzenie ze środowiska COM, tworzenie instancji i zliczanie obiektów COM, odpytywanie obiektów o obsługiwane interfejsy, a także obsługę błędów. Kompilator Microsoft Visual C++ obsługuje rozszerzenia języka C++ o nazwie C++ Attributes . Rozszerzenia te mają na celu uproszczenie opracowywania COM i usunięcie dużej części standardowego kodu wymaganego do implementacji serwerów COM w C++.

Wykorzystanie rejestru

W systemie Windows klasy COM, interfejsy i biblioteki typów są wyświetlane według identyfikatorów GUID w rejestrze , pod HKEY_CLASSES_ROOT\CLSID dla klas i HKEY_CLASSES_ROOT\Interface dla interfejsów. Biblioteki COM używają rejestru do lokalizowania poprawnych bibliotek lokalnych dla każdego obiektu COM lub lokalizacji sieciowej usługi zdalnej.

COM bez rejestracji

Rejestracja-Free COM (RegFree COM) to technologia wprowadzona w systemie Windows XP , który pozwala Component Object Model (COM) komponentów do aktywacji sklep metadanych i CLSID ( Class ID) dla komponentu bez korzystania z rejestru . Zamiast tego metadane i identyfikatory CLSID klas zaimplementowanych w składniku są deklarowane w manifeście zestawu (opisanym przy użyciu XML ), przechowywane jako zasób w pliku wykonywalnym lub jako oddzielny plik zainstalowany ze składnikiem. Umożliwia to instalowanie wielu wersji tego samego składnika w różnych katalogach, opisanych przez ich własne manifesty, a także wdrożenie XCOPY . Ta technika ma ograniczone wsparcie dla serwerów EXE COM i nie może być używana do komponentów systemowych, takich jak MDAC , MSXML , DirectX lub Internet Explorer .

Podczas ładowania aplikacji moduł ładujący systemu Windows wyszukuje manifest. Jeśli jest obecny, program ładujący dodaje z niego informacje do kontekstu aktywacji. Gdy fabryka klas COM próbuje utworzyć wystąpienie klasy, najpierw sprawdzany jest kontekst aktywacji, aby sprawdzić, czy można znaleźć implementację dla identyfikatora CLSID. Rejestr jest skanowany tylko wtedy, gdy wyszukiwanie się nie powiedzie .

Ręczne tworzenie instancji obiektów COM

Obiekty COM można również tworzyć ręcznie, podając ścieżkę do pliku DLL i identyfikator GUID obiektu. Nie wymaga to zarejestrowania biblioteki DLL ani GUID w rejestrze systemowym i nie korzysta z plików manifestu. Biblioteka COM DLL eksportuje funkcję o nazwie DllGetClassObject. Wywołanie DllGetClassObject z żądanym identyfikatorem GUID i IID_IClassFactory zapewnia wystąpienie obiektu fabryki . Obiekt Factory ma metodę CreateInstance, która może tworzyć wystąpienia obiektu na podstawie identyfikatora GUID interfejsu. Jest to ten sam proces, który jest używany wewnętrznie podczas tworzenia wystąpień zarejestrowanych składników COM.

Jeśli utworzony obiekt COM tworzy instancję innego obiektu COM przy użyciu ogólnego interfejsu API CoCreateInstance, spróbuje to zrobić w zwykły ogólny sposób, używając rejestru lub plików manifestu. Może jednak tworzyć obiekty wewnętrzne (które mogą w ogóle nie być zarejestrowane) i rozdawać do nich odniesienia do interfejsów, korzystając z własnej prywatnej wiedzy.

Przejrzystość procesów i sieci

Obiekty COM można w sposób przezroczysty tworzyć i odwoływać się w ramach tego samego procesu (w procesie), poza granicami procesu (poza procesem) lub zdalnie przez sieć (DCOM). Obiekty pozaprocesowe i zdalne używają marshallingu do serializacji wywołań metod i zwracania wartości ponad granicami procesów lub sieci. To kierowanie jest niewidoczne dla klienta, który uzyskuje dostęp do obiektu tak, jakby był to lokalny obiekt w procesie.

Gwintowanie

W modelu COM wątek jest rozwiązany za pomocą koncepcji znanej jako apartamenty . Pojedynczy obiekt COM znajduje się dokładnie w jednym mieszkaniu, które może być jednowątkowe lub wielowątkowe. Istnieją trzy typy mieszkań w COM: jednowątkowy apartament (STA) , wielowątkowy Apartament (MTA) , a wątek Neutral Apartament (NA). Każde mieszkanie reprezentuje jeden mechanizm, dzięki któremu stan wewnętrzny obiektu może być synchronizowany w wielu wątkach. Proces może składać się z wielu obiektów COM, z których niektóre mogą używać STA, a inne MTA. Wszystkie wątki uzyskujące dostęp do obiektów COM podobnie żyją w jednym mieszkaniu. Wybór apartamentu dla obiektów i wątków COM jest określany w czasie wykonywania i nie można go zmienić.

Typ apartamentu Opis
Apartament jednowątkowy ( STA ), (ThreadingModel= Apartament ) Pojedynczy wątek jest dedykowany do wykonywania metod obiektu. W takim układzie wywołania metod z wątków spoza mieszkania są marshallowane i automatycznie kolejkowane przez system (poprzez standardową kolejkę komunikatów Windows). W ten sposób środowisko wykonawcze COM zapewnia automatyczną synchronizację, aby zapewnić, że każde wywołanie metody obiektu jest zawsze wykonywane do końca przed wywołaniem innego. Deweloper nie musi więc martwić się blokowaniem wątków ani warunkami wyścigu.
Apartament wielowątkowy ( MTA ), (ThreadingModel = bezpłatny ) Środowisko wykonawcze COM nie zapewnia synchronizacji, a wiele wątków może jednocześnie wywoływać obiekty COM. W związku z tym obiekty COM muszą wykonać własną synchronizację, aby zapobiec sytuacji, w której jednoczesny dostęp z wielu wątków może spowodować sytuację wyścigu. Wywołania do obiektu MTA z wątku w STA są również organizowane.
Mieszkanie wyznaczane dynamicznie (ThreadingModel= Both ) W trybie obu apartamentów serwer automatycznie wybiera STA lub MTA podczas tworzenia obiektu, aby dopasować typ apartamentu wątku wywołującego. Może to być przydatne, aby uniknąć narzutu, gdy serwery MTA są dostępne przez wątek STA.
Apartament neutralny wątek ( NA ), (ThreadingModel = neutralny ) Wyjątkowe mieszkanie bez przypisanych wątków. Gdy wątek STA lub MTA wywołuje obiekt NA w tym samym procesie, wątek wywołujący tymczasowo opuszcza swoje mieszkanie i wykonuje kod bezpośrednio w NA bez przełączania wątków. Dlatego można myśleć o NA jako o optymalizacji efektywnych wywołań metod międzyapartamentowych.

Wątki i obiekty należące do tego samego apartamentu podlegają tym samym regułom dostępu do wątków. Wywołania metod wykonywane w tym samym mieszkaniu są zatem wykonywane bezpośrednio, bez pomocy ze strony COM. Połączenia metodowe wykonywane w różnych mieszkaniach są realizowane poprzez krosowanie. Wymaga to użycia serwerów proxy i stubów.

Krytyka

Ponieważ COM ma dość złożoną implementację, programiści mogą być rozpraszani przez niektóre problemy z „hydrauliką”.

Pompowanie wiadomości

Gdy STA jest inicjowana, tworzy ukryte okno, które jest używane do routingu wiadomości między mieszkaniami i między procesami. To okno musi mieć swoją kolejkę wiadomości regularnie "pompowaną". Ta konstrukcja jest znana jako " pompa wiadomości ". W starszych wersjach systemu Windows niewykonanie tego może spowodować zakleszczenia w całym systemie. Ten problem komplikują niektóre interfejsy API systemu Windows, które inicjują model COM w ramach swojej implementacji, co powoduje „wyciek” szczegółów implementacji.

Liczenie referencji

Zliczanie odwołań w modelu COM może powodować problemy, jeśli dwa lub więcej obiektów jest cyklicznie przywoływanych . Projekt aplikacji musi to uwzględniać, aby obiekty nie pozostały osierocone. Obiekty mogą również pozostać z aktywnymi licznikami odwołań, jeśli używany jest model „ujścia zdarzeń” COM. Ponieważ obiekt, który uruchamia zdarzenie, potrzebuje odniesienia do obiektu reagującego na zdarzenie, liczba odwołań tego ostatniego nigdy nie osiągnie zera. Cykle referencyjne są zwykle przerywane przy użyciu terminacji poza pasmem lub tożsamości dzielonych. W technice zakończenia poza pasmem obiekt ujawnia metodę, która po wywołaniu zmusza go do porzucenia odwołań do innych obiektów, przerywając w ten sposób cykl. W technice podzielonej tożsamości pojedyncza implementacja uwidacznia dwa oddzielne obiekty COM (znane również jako tożsamości). Tworzy to słabe odniesienie między obiektami COM, zapobiegając cyklowi odniesienia.

DLL Piekło

Ponieważ wewnątrzprocesowe komponenty COM są implementowane w plikach DLL, a rejestracja pozwala tylko na jedną wersję na CLSID, mogą one w niektórych sytuacjach podlegać efektowi " DLL Hell ". Funkcja COM bez rejestracji eliminuje ten problem w przypadku składników w procesie; COM bez rejestracji nie jest dostępny dla serwerów out-of-process.

Zobacz też

Uwagi

Bibliografia

Zewnętrzne linki