180 likes | 362 Views
9.3 COM und DCOM (Microsoft 1990-99). COM – Component Object Model Binärcode-Konvention für „Schnittstellen“ von „Klassen“ (= Binärcode in DLL- oder EXE-Dateien), ansprechbar über lokale „Fernaufrufe“ (in getrennten Prozessen oder in gleichem Prozess)
E N D
9.3 COM und DCOM (Microsoft 1990-99) COM – Component Object Model Binärcode-Konvention für „Schnittstellen“ von „Klassen“ (= Binärcode in DLL- oder EXE-Dateien), ansprechbar über lokale „Fernaufrufe“ (in getrennten Prozessen oder in gleichem Prozess) gute Interoperabilität zwischen Programmiersprachen DCOM – Distributed COM Architektur: Client/Server mit Fernaufrufen/erzeugung IDL: MIDL, Erweiterung der DCE IDL Dienste: Microsoft-spezifisch Anwendungen: Dienste vs9.3
9.3.1 Schnittstellen und Objekte • Schnittstelle (interface) = • (Schnittstellenbeschreibung) Menge von Operations-Signaturen, • beschrieben mit MIDL für Dokumentation (und Stub-Erzeugung) • (Schnittstellenimplementierung) Vektor von Adressen • von Prozeduren („vtable“, binär, sprachunabhängig!) • Objekt(object) = Menge von Schnittstellen gemäß • „Ein Objekt implementiert mehrere Schnittstellen“ vs9.3
Jede Schnittstelle trägt einen eindeutigen Bezeichner (interface identifier, IID, 128 bits) . Jede Schnittstelle ist Erweiterung der SchnittstelleIUnknown . Jedes Objekt implementiert die SchnittstelleIUnknown : interface IUnknown // MIDL-Text { HRESULT QueryInterface([in] REFIID iid, [out]void** ppvObject); // Adresse der Schnittstelleiidbeschaffen ULONG AddRef(void); // Verweiszähler erhöhen ULONG Release(void); // Verweiszähler verringern } vs9.3
Beispiel einer Schnittstellenbeschreibung mit Angabe eines IID: [ object, uuid(0000010C-0000-0000-C000-000000000046) ] // IID – Interface ID interface Ipersist : IUnknown { typedef [unique] IPersist *LPPERSIST; HRESULT GetClassID([out] CLSID *pClassID); } vs9.3
Typische bildliche Darstellungen: SchnittstelleIpersist Objekt mit diversen Schnittstellen QueryInterface AddRef Release GetClassID „vtable“ IUnknown IPersist . . . . vs9.3
9.3.2 COM - Component Object Model http://msdn.microsoft.com/library Component Development Klasse(class) = Binärcode für Objekterzeugung und -operationen, identifiziert durch eindeutigen class identifier, CLSID Zuordnung zwischen CLSID und Code-Datei(en) - DLL oder EXE - ist im Windows Registry vermerkt. Eine Datei kann Code für mehrere Klassen enthalten. Class Object / Class Factory = Fabrikobjekt, das erzeugt werden muß, bevor mit seiner Hilfe Objekte der zugehörigen Klasse erzeugt werden können vs9.3
Standard-Schnittstelle einer Class Factory: interface IClassFactory : IUnknown { HRESULT CreateInstance([in] IUnknown *pUnkOuter, // falls Aggregation [in] REFIID iid, // Schnittstellentyp [out]void** ppvObject); // erzeugtes Objekt, nicht initialisiert HRESULT LockServer([in] boolean lock); // Erhöhung/Verringerung des Sperrzählers } Implementierung einer Klasse muß auch eine Class Factory mit dieser Schnittstelle bereitstellen. vs9.3
Erzeugung eines privaten Objekts (!) über Class Factory: CoGetClassObject (clsid, context, NULL, IID_IClassFactory, (LPLPVOID)&factory); factory->CreateInstance(outer, iid, (LPLPVOID)&object); object->init(...); Ort der Fabrik und Objekterzeugung wird durch Bits in context bestimmt: internal: DLL im gleichen Prozess/Adressraum local: EXE in anderem Prozess/Adressraum, aber auf gleicher Station remote: DLL oder EXE auf anderer Station . . . vs9.3
Fabrikobjekt erlaubt beliebig viele Objekterzeugungen, auch mit verschiedenen Schnittstellen (soweit unterstützt). Falls nur ein Objekt benötigt wird: CoCreateInstance(clsid, outer, context, IID_IClassFactory, (LPLPVOID)&object); beinhaltetCoGetClassObject(...); factory->CreateInstance(...); factory->Release(); vs9.3
Realisierung vonCoGetClassObjectist abhängig von context : COM sucht im Registry nachclsidund zugehörigen Einträgen für DLL- und EXE-Dateien: wenn internal und DLL vorhanden, DLL laden, benutzerdefinierte Prozedur aufrufen, die Fabrik liefert: DllGetClassObject(...); sonst: wenn local und EXE vorhanden, Server-Prozess starten; dieser erzeugt Fabrik und registriert sie mit CoRegisterClassObject(...); COM wartet die Registrierung ab und lädt dann beim Klienten die Proxy DLL für die Fabrik. sonst: wenn remote – siehe 9.3.3 vs9.3
9.3.3 DCOM - Distributed COM = COM + echte Fernaufrufe + Sicherheit + Threading ( NT Servers) MIDL Compiler = Vertreter-Erzeuger, erzeugt C/C++ Code für Vertreter („proxies“) und Treiber („stubs“) Fernaufrufe: - benutzen DCE RPC, - at-most-once-Fehlersemantik, - OrphanDetection Fernerzeugung einer Objektfabrik ist möglich, wenn im lokalen Registry unter derclsidein entsprechender Eintrag steht, mit Daten RemoteServerName= Stationsname oder –adresse ActivateAtStorage= "Y" oder "N" (für Aktivierung persistenter Obj.) Codes von Klassen und Klienten sind ortstransparent! vs9.3
Benennung einer Station im Klienten-Programm: Wähle als 3. Argument von CoGetClassObject(clsid, context, server,..) einen Verweis auf Verbund vom Typ COSERVERINFO (reserviert, Stationsname oder –adresse, Autorisierung, reserviert) ! Code kann auch DLL statt EXE sein - dann wird spezielles Standard-EXE („surrogate“) geladen, welches DLL lädt. vs9.3
Objektifizieren von Daten: CoGetInstanceFromFile(server, // or NULL (local) clsid, pUnkOuter, context, fileMode, fileName, lengthOf, &resultsArray); // contains interfaces CoGetInstanceFromIStorage(...); vs9.3
9.3.4 Monikers und Running Object Table • Moniker („Spitzname“) = Verweisobjekt, z.B. File Moniker: • Objekt mit Bezug auf Datei = persistentes Objekt, • implementiert IMoniker mit Operation BindToObject, • die das persistente Objekt aktiviert – falls nicht bereits aktiv. Erzeugung:CreateFileMoniker(LPSTR pathname, LPMONIKER *pmk) Benutzung:BindToObject(.,., REFIID iid, void **ppvObject) beschafft CLSID aus Dateityp (Registry!), machtdamit CoCreateInstance (falls nicht aktiv!), lädt die Daten aus der Datei und beschafft ppvObject mittels QueryInterface vs9.3
Aktive Objekte • werden in der Running Object Table(ROT) registriert, • werden ggfls. von mehreren Prozessen gemeinsam benutzt. • Schnittstelle für ROT wird erhalten mit • GetRunningObjectTable • und hat Operationen • Register - macht Eintrag (Moniker, Objekt), liefert Kennung • GetObject - liefert Objekt für Moniker • Revoke - entfernt Eintrag mit Kennung • ... vs9.3
9.3.5 Visual J++ mit DCOM leistet gute Abstraktion von DCOM‘s technischen Details – besser als RMI MIDL beschreibt Schnittstelle IAccount für Beispiel Konto-Objekte MIDL-Java-Übersetzer erzeugt Packageaccount mit Schnittstelleaccount.IAccountund Proxyaccount.Account implements IAccount Server: import com.ms.com.*; import account.*; class Account implements IAccount { public int deposit(int a) throws ComException { .....} ..... } vs9.3
Werkzeugjavaregübernimmt Generierung und Registrierung • der zugehörigen COM-Komponente • Klient:import com.ms.com.*; • import account.*; • ... • ... • IAccount acc = (IAccount)new Account(no,bal); • ... • acc.deposit(amount); // may throw ComException • ... • newveranlasst: Erzeugung eines Vertreterobjekts, • dabei Auffinden der Komponente (Registry!) • und dort Erzeugung des Originalobjekts vs9.3
9.3.6 COM+ Sprachunabhängiges Verbergen der meisten COM/DCOM-Details: Class Factory Reference Counting Query Interface IDL ! . . . . . durch Werkzeuge zur automatischen Generierung von Fabriken, . . . . . sowie erweiterte Laufzeitunterstützung. vs9.3