Overwiew COM DLL Factory Interface Factory Pattern CLSID

  • Slides: 12
Download presentation
Overwiew COM

Overwiew COM

DLL Factory Interface Factory Pattern CLSID c fa er nt y. I er Qu

DLL Factory Interface Factory Pattern CLSID c fa er nt y. I er Qu e Aggregation Inner class 1. ) Static View – Classical (h-File in C++) 2. ) Dynamic View – Communication OO-Server mit Events EVENT 3. ) Event-Data-System DATA (werden im Blackboard Pattern angelegt) HA: 10 Fragen – Was ist eine COM-Komponente?

(D)COM = Distributed Component Object Model Inhalte: Basisinterface, Extension Interface Pattern, Reference Counting, Broker

(D)COM = Distributed Component Object Model Inhalte: Basisinterface, Extension Interface Pattern, Reference Counting, Broker Pattern, Factory Pattern COMponent: - box mit Inteface (Design by contract) Interfaces können hinzugefügt werden box-spoon-plot - abgeschlossene Funkionalität - Modul - entspricht einer Klasse, Reuseability (= Wiederverwendbarkeit) - Implementierung austauschbar, loading on demand - wie Klassenbibliothek nutzbar - remote nutzbar - load balancing - Design for Integration - unabhängig von Programmiersprache - Interface Description Language (idl) CORBA, DCOM Softwarebus: Softwarebus CORBA = Common Request Broker Architecture COM = Objectoriented Middleware + Synchrone Communication (+ Asynchrone Communication)

Basis. Interface IUnknown: interface IUnknown { virtual HRESULT __stdcall Query. Interface (const IID iid,

Basis. Interface IUnknown: interface IUnknown { virtual HRESULT __stdcall Query. Interface (const IID iid, void **ppr) = 0; virtual ULONG__stdcall Add. Ref () = 0; virtual ULONG__stdcall Release () = 0; } Bemerkung: a. ) #define interface struct (class mit public members) b. ) __stdcall (Pascal Aufrufkonvention, Methode räumt Stack vor Return auf; normalerweise räumt der Caller den Stack auf) c. ) #define STD Method CALL TYPE __stdcall d. ) HRESULT 32 -Bit-Wert (Bit 1= Severity, Bit 2 -16=Facility, Bit 17 -32= Return Code Interface-Implementierung in C++: interface IX { public: virtual void Fx 1()=0; virtual void Fx 2()=0; } Trennung Interface und Implementierung interface IY { Schnittstellenvererbung, keine Implementierungsvererbung Vererbung public: vtable wird vom Compiler generiert virtual void Fy 1()=0; virtual void Fy 2()=0; Inheritance – Implementierungsdetail ATL } nested class (Aggregation, MFC) ----class CA : public IX, IY { virtual void Fx 1() {. . . } Implementierung (h, cpp). . }

IX Virtual virtual function table: p. IX Fx 1 &Fx 1 vtbl pointer &Fx

IX Virtual virtual function table: p. IX Fx 1 &Fx 1 vtbl pointer &Fx 2 Zweistufiger Mechanismus: 1. ) look up in vtable (Funktionszeiger) 2. ) function call mit Funktionszeiger Fx 2 Enthält Zeiger auf Memberfunktionen IDispatch vtable ausimplementieren für z. B. VBasic Broker-Pattern (Sequenzdiagramm): Client. Proxy Broker Stub(Server. Proxy) Call Server Send Request Pack Data Find Server Channel Call Service Un. Pack Data Run_Service Pack Data Return Un. Pack Data Result Server

Marshaling (Pack. Data): Datenstruktur „Bytewurst“ Unmarshaling (Unpack. Data): Daten werden wieder entpackt Parameter-Classification: in

Marshaling (Pack. Data): Datenstruktur „Bytewurst“ Unmarshaling (Unpack. Data): Daten werden wieder entpackt Parameter-Classification: in out inout sind Bestandteil von idl Query Interface: CA fachliche Klasse Query Interface Add. Ref Release Fx vtable Server Client Query Interface Add. Ref Release Fx Vtbl. Pointer p. Ix HRESULT Query. Interface (const IID &iid, void ** ppv) IUnknown IX IY CX CY IX IY IUnknown Componente IUnknown

HRESULT Query. Interface (IID, IDPtr) - 32 Bit - S_OK - E_NOINTERFACE - Makro:

HRESULT Query. Interface (IID, IDPtr) - 32 Bit - S_OK - E_NOINTERFACE - Makro: SUCEEDED, FAILED Bsp. : void foo(IUnknown *p. I) { Ix * p. Ix=NULL; HRESULT hr=p. I Query. Interface(IID_IX, (void**)&p. IX); if(SUCEEDED(hr)) { p. Ix Fx(); } } ja Unterstützt Interface ein Interface IX? hr S_OK *ppv != 0 nein hr E_NOINTERFACE *ppv = 0 IUnknown IX Implementierung für Query. Interface, Add Ref, Release Class Factory Implementierung für fachliche Klasse

Implementierung von Query Interface: IUnknown Query Interface Add. Ref Release Ix Query Interface Add.

Implementierung von Query Interface: IUnknown Query Interface Add. Ref Release Ix Query Interface Add. Ref Release Iy a. ) Query Interface b. ) v. Table-Mechanismus IUnknown ULONG Bemerkung: Cast „über nächste Nachbarn“ *ppv = static_cast <IUnknown*>(static_cast <Ix*>(this)) (nicht eindeutig als Mehrfachvererbung) CA IX IY IUnknown : public: private protected public Interface IX : IUnknown { /*. . . */ } Interface IY : IUnknown { /*. . . */ } class CA: public IX, public IY { /*. . . */ }

HRESULT __stdcall CA: : Query. Interface (const IID &iid, (void **) ppv); { if(iid

HRESULT __stdcall CA: : Query. Interface (const IID &iid, (void **) ppv); { if(iid == IID_IUnknown) { *ppv = static_cast<Ix*>(this); } else if(iid == IID_IX) { *ppv = static_cast<Ix*>(this); } else if(iid == IID_IY) { *ppv = static_cast<Iy*>(this); } a. ) if-cascades substitution by hash tables else { b. ) Code: - Client wünscht Interface Ix, Iy, *ppv = NULL; IUnknown return E_NOINTERFACE; - Client wünscht anderes Interface } - Reference Counting static_cast<IUnknown*>(*ppv) Add. Ref(); - Casting ändert Wert des ppv-Zeigers return S_OK; } Virtual Function Table CA: this IX vtblpointer (IX*)CA: this IY vtblpointer (IY*)CA: this Instance Data Query. Interface Add. Ref Release Fx

Eigenschaften von Query Interface: 1. ) Query. Interface ist symmetrisch p. Ix QI(IID_Y, .

Eigenschaften von Query Interface: 1. ) Query. Interface ist symmetrisch p. Ix QI(IID_Y, . . . ) p. Iy : QI(IX) IY p. Iy QI(IID_X, . . . ) p. Ix : QI(QI(IX) IX 2. ) Query. Interface ist transitiv p. Ix QI(IID_Y, . . . ) p. Iy QI(IID_Z, . . . ) p. Iz 3. ) Query. Interface ist reflexiv p. Ix QI(IID_X, . . . ) p. Ix IUnknown IX IY IZ ÜA: Identität des Interface-Zeigers Frage: Wann gehören p. Ix und p. Iy zur gleichen Komponente? Wie kann man rausfinden, ob zwei Interface-Zeiger zur gleichen Komponente gehören?

Reference Counting: Lifetime Control Regeln: 1. ) Call Add. Ref before Return Bsp. :

Reference Counting: Lifetime Control Regeln: 1. ) Call Add. Ref before Return Bsp. : QI, Create. Instance 2. ) Call Release when you are done 3. ) Call Add. Ref after assignment Garbage Collection delete this mit Bedingung m_m. Ref=0

Klassifikation von Klassen: 1. ) Nicht-modale Klassen besitzen keine Beschränkung Attribute hinsichtlich der Aufrufreihenfolge

Klassifikation von Klassen: 1. ) Nicht-modale Klassen besitzen keine Beschränkung Attribute hinsichtlich der Aufrufreihenfolge ihrer Methoden. Methode Bsp. : class Date. Time set(), get(), compare. Equal(), . . . Stateless Objects und State Objects 2. ) Unimodale Klassen Beschränkung der Aufrufreihenfolge (Design by Contract) ihrer Methoden, aber unabhängig vom Zustand (Attributinhalt). Bsp. : class Ampel rotes. Licht. Ein(), gelbes. Licht. Ein(), . . . 3. ) Quasimodale Klassen Beschränkung der Aufrufreihenfolge ihrer Methoden ausschließlich basierend auf den aktuellen (State Change in der State Chart) Zustand. Bsp. : class Stapel push() wenn der Stapel gefüllt kann nichts mehr draufgelegt werden 4. ) Modale Klassen Beschränkung der Aufrufreihenfolge (State Change in der State Chart) hinsichtlich ihrer Methode und ihrer Zustände (Attributbelegung). Unimodal call sequence of methods from design by contract Quasimodal State Chart Bind Recovery Find Recovery