1 / 63

Komponentowe systemy rozproszone

Komponentowe systemy rozproszone. COM i inni. Komunikacja/komponenty w WINDOWS w ujęciu historycznym. Schowek DDE 16-bitowe OLE 1.0 16-bitowe OLE 2.0 OLE 2.0 = COM = ActiveX 32-bitowe OLE Dcom COM+ = COM + MTS + MSMQ. Component Object Model. Binarny standard komunikacji

orli
Download Presentation

Komponentowe systemy rozproszone

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Komponentowe systemy rozproszone COM i inni

  2. Komunikacja/komponenty w WINDOWS w ujęciu historycznym • Schowek • DDE • 16-bitowe OLE 1.0 • 16-bitowe OLE 2.0 • OLE 2.0 = COM = ActiveX • 32-bitowe OLE • Dcom • COM+ = COM + MTS + MSMQ

  3. Component Object Model • Binarny standard komunikacji • Nie jest językiem • Niewymagakonketnegojęzyka • Niezależnyodjęzyka • Zarządzaniezasobami • Interfejsy – standard komunikacji • Identyfikacjaobiektówiusług • (Pół)Automatycznemetodymarszalingudanych • Wspiera: enkapsulację, dziedziczenieinterfejsuiimplementacji, polimorfizm

  4. Obiektowy model klient- serwer

  5. Rodzaje serwerów COM • serwer w procesie = bibliotekadynamicznaInprocServer / InprocServer32 • serwerlokalny = oddzielny proces wykonywalnylokalnieLocalServer / LocalServer32 • serwerzdalny = proces wykonywalnyzdalnieRemoteServer/ RemoteServer32

  6. COM – zarządzanie obiektem • Zarządzaniepamięcią • czasżycia - zliczaniereferencji • zarządzaniekopiamidanychprzekazywanymimiędzyobiektami • Zunifikowanysposóbtworzenia / likwidowania

  7. COM – identyfikacja klas • GUID - globalnieunikalnyidentyfikator:128-bitowa liczbanp.: B77D61E0-47D8-11d0-B53F-444553540000 • CLSID - GUID identyfikującyklasęobiektu • IID - GUID identyfikującyinterfejs (niezbędnygdymamy do czynienia z marszalingiemdanych) Generowanie GUID: • przezużytkownika - GUIDGEN.EXE, UUIDGEN.EXE • Przezśrodowiskonp .NET, VB, VC++ • przez API - funkcjaCoCreateGuid

  8. Tworzenie obiektów • Indywidualna funkcja tworzaca obiekty • CoCreateObject() – wymaga dostarczenia IClassFactory

  9. "Ręczne "tworzenie COM-a– InProcess DllGetClassObject(CLSID_Test, IID_IClassFactory, (void**)pClassFactory); pClassFactory->CreateInstance( NULL, IID_Test, (void**)pTest); pClassFactory->Release();

  10. class ComClientClass { ... virtual DoSmthg(int); } * pInterface; Klient COM if (! FAILED(CoInitialize(NULL))) { err = (CoCreateInstance(CLSID_TESTCLASS, NULL,CLSCTX_INPROC_SERVER, IID_TESTINTERFACE, (void **)&pInterface) ); //użycie COM-a pInterface->DoSmthg(5); //zwolnienie COM-a pInterface->Release(); CoUninitialise(); } CLSCTX_ALL CLSCTX_INPROC_SERVER CLSCTX_LOCAL_SERVER

  11. Powiązanie obiektu z serwerem • systemowabazadanych (rejestrsystemu) - REGEDIT.EXE:HKEY_CLASSES_ROOT CLSID{GUIDklasyobiektu} = OpisklasyobiektuProgID = Producent.Serwer.WersjaVersionIndependentProgID = Producent.SerwerRodzajSerwera = Pełnanazwa (ześcieżką) InsertableProducent.Serwer.Wersja = OpisklasyobiektuCLSID = {GUIDklasyobiektu} Producent.Program = Opisklasyobiektu (bezwersji)CurVer = Producent.Serwer.Wersjafunkcje: ProgIDFromCLSIDCLSIDFromProgID

  12. RejestracjaCOM-a • ”ręczne” uruchomienie pliku typu .REG • automatyczny import pliku .REG • bezpośrednia manipulacja rejestrem • obsługa /REGISTER i /UNREGISTER

  13. COM - interfejsy • Koncepcja interfejsu: • kontrakt na realizację pakietu usług • niezależny od języków programowania sposób opisu: • IDL • Biblioteki typów TLB • odpowiednik tablicy wskaźników do funkcji: • C, C++, Pascal • Java • VB

  14. Realizacja interfejsu w C++ class CBeeper: CUnknown { public: // wysokośćdźwięku long m_lSound ; // wydaniedźwięku long GetSound (); void SetSound (long lSound); long Beep () ; } ptr = CoCreateInstance(....); (CBeeper)ptr->Beep(); interface IBeeper : IUnknown{ long GetSound (); void SetSound (long lSound); long Beep () ;};

  15. Realizacja interfejsu w C++

  16. Interfejsy HKEY_CLASSES_ROOTCLSID{a123x3y1-4ce6-4ce6-4ce6-2a212123223} = My Prog Proxy = Ole2.dll InprocServer32 = c:\\coms\\myserver.dllLocalServer32 = c:\\coms\\myserver.exe{x111111-4ce6-4ce6-4ce6-2a212123223}InprocServer32 = c:\\coms\\mystub.dllInterface{a123x3y1-4ce6-4ce6-4ce6-2a212123223} NumMethodsBaseInterfaceProxyStubClsId = {x111111-4ce6-4ce6-4ce6-2a212123223}

  17. SkryptIDL • Językopisuinterfejsów [uuid(108dbc1b-1ad2-4bda-b45a-e6b0f014c3a1),object] interface IMKInterface : IUnknown { import "unknwn.idl"; HRESULT TransformTxt([in,out,string]char *file); HRESULT GetMaxLen([out]WORD *dw); HRESULT SetMaxLen([in] WORD dw); } • MIDL.EXE – kompilacja IDL do: • bibliotekitypów • zrodla w c dla stub-a (dll) szeregującego

  18. Biblioteka typów • Możebyćlinkowanajakozasóblubdostępnaoddzielnie: HKEY_CLASSES_ROOTCLSID{a123x3y1-4ce6-4ce6-4ce6-2a212123223} = My ProgProgID= Producent.Serwer.WersjaTypeLib= {a123x3y1-4ce6-4ce6-4ce6-a2121223} TypeLib{a123x3y1-4ce6-4ce6-4ce6-a2121223} = My Type LibDir = c:\tmpHelpDir= c:\tmp\Help1.0 0 = Any.TLB9 = English.TLB

  19. IUnknown - podstawowy interfejs obiektu • każdy obiekt odostępnia interfejs IUnknown • każdy interfejs obejmuje (dziedziczy) IUnknown

  20. Właściwości Interfejsów • Statyczny (niezmienny w czasie) zestawinterfejsów • JednoznacznyiunikatowyIUnknowndlaróżnychobiektów • Zadazwrotności: IA -> IA • Zasadasymetrii: IA -> IB -> IA • Zasadaprzechodniości: IA -> IB -> IC i IA -> IC

  21. IUnknown - funkcjonalność interface IUnknown { // zwiększalicznikodniesień ULONG AddRef () ; // zmniejszalicznikodniesień, // gdylicznik == 0 to zwalniaobiekt ULONG Release () ; // udostępniainterfejsy do obiektu HRESULT QueryInterface ( REFIID riid,// identyfikatorinterfejsuvoid** ppvObj) ;// wskaźnik do zwracanegointerf. } ;

  22. IUnknown – realizacja w C++ class IUnknown { public: virtual HRESULT QueryInterface (REFIID, void**) ; virtual ULONG AddRef () ; virtual ULONG Release () ; } ; class IUnknown { public: STDMETHODIMP QueryInterface (REFIID, void**) ; STDMETHODIMP_(ULONG) AddRef () ; STDMETHODIMP_(ULONG) Release () ; } ; Makra MFC

  23. Zliczanie odniesień • Tworzeniekopiiodniesienia do obiektu – AddRef • Unieważnienieodniesienia do obiektu – Release W praktyceAddRef / Release • Zwrotreferencjiprzezfunkcję • Przekazanieodniesienia do oddzielnegowątku

  24. Zarządzanie obiektami przez zliczanie odniesień class CXxxObject : public IUnknown { public: CXxxObject (…): m_cRef (0) {…} ; virtual HRESULT QueryInterface (REFIID, void**) ; virtual ULONG AddRef () ; virtual ULONG Release () ; … private: ULONG m_cRef ; // licznikodniesień … } ;

  25. IUnknown::AddRef / Release ULONG CXxxObject::AddRef () { return ++m_cRef; // licznikodniesień } ULONG CXxxObject::Release () {if (0 != --m_cRef) // licznikodniesień return m_cRef ; delete this ; // usunięcieobiektu return 0 ; }

  26. IUnknown::QueryInterface HRESULT CXxxObject::QueryInterface ( REFIID riid, void** ppvObj) {*ppvObj = NULL ; if ( IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IMyInterface) ) // if (riid == IID_IUnknown || riid == IID_IMyInterface) *ppvObj = this ; if (NULL != *ppvObj) { ((IUnknown)*ppvObj)->AddRef(); //licznikodniesień return NOERROR ;} else return E_NOINTERFACE; }

  27. IClassFactory - tworzenie obiektów interface IClassFactory : public IUnknown { // stworzenieobiektu HRESULT CreateInstance(IUnknown* pUnkOuter,// wskaźnik do obiektunadrzęd.REFIID riid,// podstawowyinterfejsobiektu void** ppvObj) ;// wskaźnik do zwracanegointerf. // zablokowanieserwera w pamięci HRESULT LockServer(BOOL fLock); } ;

  28. Realizacja wielu interfejsów? Techniczny problem w przypadkurealizacjiinterfejsówjakooddzielnychklas pot. problem z powolywaniem do zyciaizarzadzaniewieloma POWIĄZANYMI obiektami możliwerozwiązanie: klasyzagnieżdzone MFC – BEGIN/END_INTERFACE_PART metody z IUnknownsądelegowne do klasygłównej

  29. Serwer w procesie (in-process) • bibliotekadynamicznaudostępniającafunkcje: STDAPI DllGetClassObject ( REFCLSID rclsid,// GUID klasyudostępnianychobiektów REFIID riid,// GUID łączatworzącegoobiekty// (zwykleIID_ClassFactory) void** ppv) ;// wskaźnik do zwracanegołącza STDAPI DllCanUnloadNow () ;

  30. Funkcje serwera typu InProcess STDAPI DllGetClassObject(REFCLSID rclsid,REFIIDriid,void**ppv) {if (rclsid != CLSID_XXX) return ResultFromScode (E_FAIL) ; CXxxClassFactory* pObj = new CXxxClassFactory;if (pObj == NULL) return ResultFromScode(E_OUTOFMEMORY); HRESULT hr = pObj->QueryInterface (riid, ppv) ;if (FAILED (hr)) delete pObj ;return hr; } STDAPI DllCanUnloadNow () {SCODE sc = (/*czysąobiekty? */…) ? S_FALSE : S_OK ;return ResultFromScode (sc); }

  31. Klient COM Server COM CoCreateInstance CLSID {123434-23213-2323-4234} InprocServer32 = “test.dll” CoGetClassObject ReadRegistry CoLoadLibrary(“test.dll”,TRUE) Hmodule = LoadLiibrary(test.dll) DllMain GetProcAdress(hModule, ”DllGetClassObject”) DllGetClassObject DllGetClassObject pFactory->QueryInterface pFactory->AddRef pFactory->CreateInstance pFactory-> CreateInstance pObject->QueryInterface pObject->AddRef pFactory->Release pFactory->Release

  32. Serwer lokalny • program wykonywalnyrejestrującyudostępnianeobiekty: • zagadnienia • utrzymanieprogramu w pamięcidopókiistniejąobiekty • pot. różnywygląd w zależnościodtypupracy (/embeeded) STDAPI CoRegisterClassObject( REFCLSID rclsid,// GUID klasyobiektów IUnknown * pUnk, // InterfejsIUnknown// udostępnianegoobiektu DWORD dwClsCtxt,// Rodzajserwera DWORD flags,// Sposóbnawiązywaniapołączenia DWORD** pdwReg// Wskaźnik do zarejestrowanej klasy );  

  33. Inicjalizacjaizakończenieserweralokalnego // inicjalizacja if (FAILED (CoInitializeEx (NULL))) …// błądinicjalizacji CXxxClassFactory* pClassFact = new CXxxClassFactory ; pClassFact->AddRef () ; DWORD dwReg; if (FAILED (CoRegisterClassObject(CLSID_XXX, pClassFact,CLSCTX_LOCAL_SERVER,REGCLS_MULTIPLEUSE, &dwReg))) … // błądinicjalizacji // zakończenie CoRevokeClassObject (dwReg) ; pClassFact->Release () ; CoUninitializeEx() ;

  34. COM – marszalingdanych między procesami Wymagane jest zarejestrowanie interfejsów

  35. Interfejsy HKEY_CLASSES_ROOTCLSID{a123x3y1-4ce6-4ce6-4ce6-2a212123223} = My Prog Proxy = Ole2.dll InprocServer32 = c:\\coms\\myserver.dllLocalServer32 = c:\\coms\\myserver.exe{x111111-4ce6-4ce6-4ce6-2a212123223}InprocServer32 = c:\\coms\\mystub.dllInterface{a123x3y1-4ce6-4ce6-4ce6-2a212123223} NumMethodsBaseInterfaceProxyStubClsId = {x111111-4ce6-4ce6-4ce6-2a212123223}

  36. Wielokrotne wykorzystywanie (reusability) kodu • C++ • dziedziczenie • wspólne pola danych dla klasy podstawowej i pochodnej • wymaga bardzo dokładnego dokumentowania, zwykle przez udostępnianie kodu źródłowego • COM • zawieranie obiektów • agregacja obiektów

  37. Zawieranie obiektów • modyfikacjametodobiektu • obiektzewnętrznynieudostępniałączaIUnknownobiektuwewnętrznego • obiektzewnętrznyudostępniapośredniowybranełączaobiektuwewnętrznego

  38. Zawieranie obiektów - zewnętrzny obiekt class CExtObject: IUnknown, IInterfaceW, IInterfaceZ { public:CExtObject (…): m_pInObj (NULL){ ::CoCreateInstance (CLSID_ExtObject, NULL, CLSCTX_ALL, IID_IUnknown,&m_pInObj) ;} ; ~CExtObject () { Release();delete m_pInObj; } ; … // metodyłączIInterfaceZiIInterfaceW private:IUnknown* m_pInObj ; // obiektwewnętrzny… } ;

  39. Agregacja obiektów • udostępnienieniezmienionychmetodobiektu • obiektzewnętrznyudostępniapośredniołączeIUnknownobiektuwewnętrznego • obiektzewnętrznyudostępniabezpośredniopozostałełączaobiektuwewnętrznego

  40. Agregacja - wewnętrzny obiekt class CInObject : IUnknown, IInterfaceW { public:CInObject (IUnknown* pUnkOuter, …) ; virtual HRESULT QueryInterface (REFIID, void**) ; virtual ULONG AddRef () ; virtual ULONG Release () ; … private:ULONG m_cRef ;// licznikodniesień IUnknown *m_pUnkOuter ; // zewnętrzneIUnknown … } ;

  41. Agregacja – zliczanie odniesień CInObject:: CInObject(IUnknown* pUnkOuter, …)m_cRef (0), m_pUnkOuter (pUnkOuter) { … } ULONG CInObject::AddRef (){ if (m_pUnkOuter) return m_pUnkOuter->AddRef () ; return ++m_cRef ; } ULONG CInObject::Release (){ if (m_pUnkOuter) return m_pUnkOuter->Release () ; if (0 != --m_cRef) return m_cRef ; delete this ; return 0 ; }

  42. Agregacja - QueryInterface HRESULT CInObject::QueryInterface (REFIID riid, void** ppvObj) {*ppvObj = NULL ; if (m_pUnkOuter) return m_pUnkOuter->QueryInterface(riid, ppvObj); if (IsEqualIID (riid, IID_IUnknown) ||IsEqualIID (riid, IID_IInterface1)) *ppvObj = this ; if (NULL != *ppvObj) { ((LPUNKNOWN)*ppvObj)->AddRef () ; return NOERROR ;}return ResultFromScode (E_NOINTERFACE) ; }

  43. Agregacja – CreateInstance HRESULT CInClassFactory::CreateInstance ( IUnknown* pUnkOuter, REFIID riid, void** ppvObj) {*ppvObj = NULL ; if (pUnkOuter && riid != IID_IUnknown) return ResultFromScode (E_NOINTERFACE); CInObjectpObj = new CInObject (pUnkOuter, …) ; HRESULT hr = pObj->QueryInterface (riid, ppvObj) ; if (FAILED (hr)) delete pObj ; else *ppvObj = pObj ; return hr ; }

  44. ActiveX Kontrolki, Serwery • Kontrolki ActiveX: • standard do rozszerzaniazestawupóldialogowychdostępnych w systemie Windows • poprzedniestandardy:Custom Controls, Visual Basic Controls • OCX = ActiveX (OLE controls = ActiveX controls) • gotowekomponentyfunkcjonalne do budowaniaprogramów • Server ActiveX: program udostępniającyIDispatch

  45. RealizacjainterfejsuIDispatch w C++ interface IDispatch: IUnknown {HRESULT GetTypeInfoCount (…) ; HRESULT GetTypeInfo (…) ; HRESULT GetIDsOfNames (…) ; HRESULT Invoke (DISPID dispID, REFIID riid, LCID lcid, unsigned short wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, unsigned int* puArgErr) ; } ;

  46. Implementacja klienta automatyzacji - Visual Basic Dim ThisExcel As Excel.ApplicationDim ThisChart As Excel.Chart Private Sub Command1_Click()Timer1.Enabled = Not Timer1.EnabledIf Timer1.Enabled Then Command1.Caption = "&Pause Chart Turning"Else Command1.Caption = "&Resume Chart Turning"End If End Sub Private Sub Timer1_Timer()Static iRotateWith ThisChart .Rotation = iRotateEnd WithiRotate = (iRotate + 5) Mod 360 End Sub

  47. Private SubForm_Load() Dim TitleArray As VariantDim DataArray As VariantTitleArray = Array("Dogs", "Cats", "Horses")DataArray = Array(34, 53, 12) Set ThisExcel = CreateObject("Excel.application")With ThisExcel .Workbooks.Add .Range("A1:C1").Value = TitleArray .Range("A2:C2").Value = DataArray .Range("A1:C2").Select Set ThisChart = .Charts.Add() .Visible = TrueEnd WithWith ThisChart .Type = Excel.Constants.xl3DColumn .HasLegend = FalseEnd WithCommand1_Click End Sub

  48. Implementacjaklientaautomatyzacji– C++ CExcelApplication * app = new CExcelApplication(.....); //app-> Attach(....); App->Workbooks.Add();

  49. Dedykowanyklientautomatyzacji MFC/.Netpotrafiąwygenerowaćklasęudostępniającąfunkcjonalnośćobiektu ActiveX napostawie: • biblioteki TLB (równieżnp. wkompilowanej w dll) • zawartościrejestru (ID.klasy) • klasapośredniczy w wołaniumetodserwera • dostępie do póludostepnianychprzezserwer (Get/Set) CMyComClassDriver c; c.CreateDispatch(ComObjectCLSID); x = c.Calculate(15); c.ReleaseDispatch();

  50. Klientautomatyzacji - VC++ CLSID clsid; IDispatch* pIDispatch ; ::CLSIDFromProgID(T2OLE(_T("Excel.application")),&clsid); HRESULT hr = ::CoCreateInstance (clsid, NULL, CLSCTX_SERVER,IID_IDispatch, (void**) &pIDispatch); CApplication m_pThisExcel = new CApplication (pIDispatch) ; CChart*m_pThisChart =new CChart(CCharts(m_pThisExcel->Charts ()).Add ()); CRange( m_pThisExcel->Range("A1", "C1")).SetValue(TitleArray); CRange (m_pThisExcel->Range ("A1", "C2")).Select () ; m_pThisExcel->SetVisible (TRUE) ; m_pThisChart->SetRotation (iRotate) ;

More Related