Komponentowe systemy rozproszone

Slides:



Advertisements
Podobne prezentacje
C++ wykład 2 ( ) Klasy i obiekty.
Advertisements

Programowanie obiektowe
Programowanie obiektowe
Projektowanie bazy danych
Wskaźniki repetytorium Wskaźniki int Y = 1, X = 2; X = 5; int *p = &X; Y X p 4 4 p = &Y; *p = 4; 5.
Klasy i obiekty.
Generics w .NET 2.0 Łukasz Rzeszot.
Bezpieczeństwo wyjątków w C++: OpenGL
Systemy rozproszone W. Bartkiewicz
Systemy rozproszone W. Bartkiewicz
CORBA Łukasz Wnęk.
Programowanie obiektowe w Javie
OOP - programowanie zorientowane obiektowo w VB.NET
20/09/ Języki programowania 1 Piotr Górczyński Kreator form.
COM Maciej Głowacki
RMI I RMI-IIOP Wprowadzenie Co to jest RMI?
Internet Communication Engine
Tworzenie ASP.NET Web Form
Arkadiusz Twardoń ZTiPSK
Programowanie w środowiskach zintegrowanych wykład 1 PSZ Programowanie w Środowiskach Zintegrowanych > Systemy i środowiska zintegrowane > Środowisko zintegrowane.
Biblioteki i przestrzenie nazw
C++ wykład 2 ( ) Klasy i obiekty.
Wykład 8 Wojciech Pieprzyca
Wstęp do programowania obiektowego
Język Java Wielowątkowość.
Budowa, przeglądanie i modyfikacja
C# Windows Forms Zastosowania Informatyki Wykład 3
Podstawy C# Grupa .NET PO.
A ctive S erver P ages Technologia dostępu do danych.
Programowanie obiektowe w C++
Tworzenie aplikacji mobilnych
Programowanie obiektowe III rok EiT
Programowanie Windows na przykładzie C# część 1
Mechanizm OLE ang. Object Linking and Embedding źródła:
Programowanie obiektowe – zastosowanie języka Java SE
Java – coś na temat Klas Piotr Rosik
Inicjalizacja i sprzątanie
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 8.
Programowanie obiektowe – język C++
Programowanie obiektowe 2013/2014
  ELEMENTY JĘZYKA JAVA komentarze w Javie, słowa kluczowe i operatory, proste typy danych, tablice, podstawowy zestaw instrukcji.
OCPJP Inner classes.
Programowanie w języku C++
Model obiektowy bazy danych
Diagram klas Kluczowymi elementami są: klasy (class)
Oprogramowanie komponentowe w środowisku Microsoft Katarzyna Kuźniar 4 FDA, C1.
Kurs języka C++ – wykład 4 ( )
Technologie internetowe Wykład 5 Wprowadzenie do skrytpów serwerowych.
Paweł Starzyk Obiektowe metody projektowania systemów
Obiekty COM Przemysław Buczkowski. Plan prezentacji 1.Wprowadzenie do COM 2.Historia standardu 3.Jak działa COM 4.Interface IUknown 5.Paradygmaty COM.
Platforma .Net.
Programowanie Zaawansowane
Wykład 11 Aplikacje SDI PO11-1 / 22 Single Document Interface 1.Klasy aplikacji SDI 2.Menu systemowe aplikacji SDI 3.Serializacja 4.Tworzenie widoku 5.Tworzenie.
Partnerstwo dla Przyszłości 1 Lekcja 27 Klasy i obiekty.
Partnerstwo dla Przyszłości 1 Lekcja 28 Dziedziczenie i rodzaje dziedziczenia.
Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego Matuszyka Podstawy.
Języki i technologie wytwarzania stron WWW Autor: Michał Walkowski Referat.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
Komponentowe systemy rozproszone COM i inni. Komunikacja/komponenty w WINDOWS w ujęciu historycznym 1. Schowek 2. DDE bitowe OLE bitowe.
Programowanie Obiektowe – Wykład 6
(według:
Programowanie Obiektowe – Wykład 2
Visual Basic w programie Microsoft Excel
Aplikacje i usługi internetowe
Założenia projektowe Javy
Język C++ Typy Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego.
Zapis prezentacji:

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 Nie jest językiem Nie wymaga konketnego języka Niezależny od języka Zarządzanie zasobami Interfejsy – standard komunikacji Identyfikacja obiektów i usług (Pół)Automatyczne metody marszalingu danych Wspiera: enkapsulację, dziedziczenie interfejsu i implementacji, polimorfizm

Obiektowy model klient - serwer

Rodzaje serwerów COM serwer w procesie = biblioteka dynamiczna InprocServer / InprocServer32 serwer lokalny = oddzielny proces wykonywalny lokalnie LocalServer / LocalServer32 serwer zdalny = proces wykonywalny zdalnie RemoteServer / RemoteServer32

COM – zarządzanie obiektem Zarządzanie pamięcią czas życia - zliczanie referencji zarządzanie kopiami danych przekazywanymi między obiektami Zunifikowany sposób tworzenia / likwidowania

COM – identyfikacja klas GUID - globalnie unikalny identyfikator: 128-bitowa liczba np.: B77D61E0-47D8-11d0-B53F-444553540000 CLSID - GUID identyfikujący klasę obiektu IID - GUID identyfikujący interfejs (niezbędny gdy mamy do czynienia z marszalingiem danych) Generowanie GUID: przez użytkownika - GUIDGEN.EXE, UUIDGEN.EXE Przez środowisko np .NET, VB, VC++ przez API - funkcja CoCreateGuid

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

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

Klient COM 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

Powiązanie obiektu z serwerem systemowa baza danych (rejestr systemu) - REGEDIT.EXE: HKEY_CLASSES_ROOT CLSID {GUID klasy obiektu} = Opis klasy obiektu ProgID = Producent.Serwer.Wersja VersionIndependentProgID = Producent.Serwer RodzajSerwera = Pełna nazwa (ze ścieżką) Insertable Producent.Serwer.Wersja = Opis klasy obiektu CLSID = {GUID klasy obiektu} Producent.Program = Opis klasy obiektu (bez wersji) CurVer = Producent.Serwer.Wersja funkcje: ProgIDFromCLSID  CLSIDFromProgID

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

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

Realizacja interfejsu w C++ class CBeeper: CUnknown { public: // wysokość dźwięku long m_lSound ; // wydanie dź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 () ; };

Realizacja interfejsu w C++

Interfejsy HKEY_CLASSES_ROOT CLSID {a123x3y1-4ce6-4ce6-4ce6-2a212123223} = My Prog Proxy = Ole2.dll InprocServer32 = c:\\coms\\myserver.dll LocalServer32 = c:\\coms\\myserver.exe {x111111-4ce6-4ce6-4ce6-2a212123223} InprocServer32 = c:\\coms\\mystub.dll Interface {a123x3y1-4ce6-4ce6-4ce6-2a212123223} NumMethods BaseInterface ProxyStubClsId = {x111111-4ce6-4ce6-4ce6-2a212123223}

Skrypt IDL Język opisu interfejsów MIDL.EXE – kompilacja IDL do: [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: biblioteki typów zrodla w c dla stub-a (dll) szeregującego

Biblioteka typów Może być linkowana jako zasób lub dostępna oddzielnie: HKEY_CLASSES_ROOT CLSID {a123x3y1-4ce6-4ce6-4ce6-2a212123223} = My Prog ProgID = Producent.Serwer.Wersja TypeLib = {a123x3y1-4ce6-4ce6-4ce6-a2121223} TypeLib {a123x3y1-4ce6-4ce6-4ce6-a2121223} = My Type Lib Dir = c:\tmp HelpDir = c:\tmp\Help 1.0 0 = Any.TLB 9 = English.TLB

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

Właściwości Interfejsów Statyczny (niezmienny w czasie) zestaw interfejsów Jednoznaczny i unikatowy IUnknown dla różnych obiektów Zada zwrotności: IA -> IA Zasada symetrii: IA -> IB -> IA Zasada przechodniości: IA -> IB -> IC i IA -> IC

IUnknown - funkcjonalność interface IUnknown { // zwiększa licznik odniesień ULONG AddRef () ; // zmniejsza licznik odniesień, // gdy licznik == 0 to zwalnia obiekt ULONG Release () ; // udostępnia interfejsy do obiektu HRESULT QueryInterface ( REFIID riid, // identyfikator interfejsu void** ppvObj) ; // wskaźnik do zwracanego interf. } ;

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

Zliczanie odniesień Tworzenie kopii odniesienia do obiektu – AddRef Unieważnienie odniesienia do obiektu – Release W praktyce AddRef / Release Zwrot referencji przez funkcję Przekazanie odniesienia do oddzielnego wątku

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 ; // licznik odniesień … } ;

IUnknown::AddRef / Release ULONG CXxxObject::AddRef () { return ++m_cRef; // licznik odniesień } ULONG CXxxObject::Release () { if (0 != --m_cRef) // licznik odniesień return m_cRef ; delete this ; // usunięcie obiektu return 0 ;

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 (); //licznik odniesień return NOERROR ; } else return E_NOINTERFACE; }

IClassFactory - tworzenie obiektów interface IClassFactory : public IUnknown { // stworzenie obiektu HRESULT CreateInstance( IUnknown* pUnkOuter, // wskaźnik do obiektu nadrzęd. REFIID riid, // podstawowy interfejs obiektu void** ppvObj) ; // wskaźnik do zwracanego interf. // zablokowanie serwera w pamięci HRESULT LockServer( BOOL fLock ); } ;

Realizacja wielu interfejsów? Techniczny problem w przypadku realizacji interfejsów jako oddzielnych klas pot. problem z powolywaniem do zycia i zarzadzanie wieloma POWIĄZANYMI obiektami możliwe rozwiązanie: klasy zagnieżdzone MFC – BEGIN/END_INTERFACE_PART metody z IUnknown są delegowne do klasy głównej

Implementacja ClassFactory class CXxxObject ; // klasa tworzonych obiektów class CXxxClassFactory : public IClassFactory { public: // IUnknown STDMETHODIMP QueryInterface (REFIID, void**) ; STDMETHODIMP_(ULONG) AddRef () ; STDMETHODIMP_(ULONG) Release () ; // IClassFactory STDMETHODIMP CreateInstance ( IUnknown*, REFIID, void**) ; STDMETHODIMP LockServer (BOOL) ; private: … } ;  

IClassFactory::CreateInstance STDMETHODIMP CXxxClassFactory::CreateInstance ( IUnknown* pUnkOuter, REFIID riid, void** ppvObj) { *ppvObj = NULL ; if (NULL != pUnkOuter) // obiekt nie wspiera agregacji return ResultFromScode(CLASS_E_NOAGGREGATION); // stworzenie obiektu CXxxObject pObj = new CXxxObject ; // udostepnienie żądanego łącza HRESULT hr = pObj->QueryInterface (riid, ppvObj) ; if (FAILED (hr)) delete pObj ; else *ppvObj = pObj ; return hr ; }

IClassFactory MFC DECLARE_OLECREATE(klasa) IMPLEMENT_OLECREATE(klasa,”identyfikator”,id_lo ng1, id_word2, id_word3, id_byte4, id_byte5 …) DECLARE_DYNCREATE(klasa) IMPLEMENT_DYNCREATE(klasa, klasa_bazowa)

Serwer w procesie (in-process) biblioteka dynamiczna udostępniająca funkcje: STDAPI DllGetClassObject ( REFCLSID rclsid, // GUID klasy udostępnianych obiektów REFIID riid, // GUID łącza tworzącego obiekty // (zwykle IID_ClassFactory) void** ppv) ; // wskaźnik do zwracanego łącza STDAPI DllCanUnloadNow () ;

Funkcje serwera typu InProcess STDAPI DllGetClassObject(REFCLSID rclsid,REFIID riid,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 = (/*czy są obiekty? */…) ? S_FALSE : S_OK ; return ResultFromScode (sc);

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

Serwer lokalny program wykonywalny rejestrujący udostępniane obiekty: zagadnienia utrzymanie programu w pamięci dopóki istnieją obiekty pot. różny wygląd w zależności od typu pracy (/embeeded) STDAPI CoRegisterClassObject( REFCLSID rclsid, // GUID klasy obiektów IUnknown * pUnk, // Interfejs IUnknown // udostępnianego obiektu DWORD dwClsCtxt, // Rodzaj serwera DWORD flags, // Sposób nawiązywania połączenia DWORD** pdwReg // Wskaźnik do zarejestrowanej klasy );    

Inicjalizacja i zakończenie serwera lokalnego // inicjalizacja if (FAILED (CoInitializeEx (NULL))) … // błąd inicjalizacji CXxxClassFactory* pClassFact = new CXxxClassFactory ; pClassFact->AddRef () ; DWORD dwReg ; if (FAILED (CoRegisterClassObject(CLSID_XXX, pClassFact,CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwReg)) ) // zakończenie CoRevokeClassObject (dwReg) ; pClassFact->Release () ; CoUninitializeEx () ;

COM – marszaling danych między procesami Wymagane jest zarejestrowanie interfejsów

Interfejsy HKEY_CLASSES_ROOT CLSID {a123x3y1-4ce6-4ce6-4ce6-2a212123223} = My Prog Proxy = Ole2.dll InprocServer32 = c:\\coms\\myserver.dll LocalServer32 = c:\\coms\\myserver.exe {x111111-4ce6-4ce6-4ce6-2a212123223} InprocServer32 = c:\\coms\\mystub.dll Interface {a123x3y1-4ce6-4ce6-4ce6-2a212123223} NumMethods BaseInterface ProxyStubClsId = {x111111-4ce6-4ce6-4ce6-2a212123223}

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

Zawieranie obiektów modyfikacja metod obiektu obiekt zewnętrzny nie udostępnia łącza IUnknown obiektu wewnętrznego obiekt zewnętrzny udostępnia pośrednio wybrane łącza obiektu wewnętrznego

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 łącz IInterfaceZ i IInterfaceW private: IUnknown* m_pInObj ; // obiekt wewnętrzny … } ;

Agregacja obiektów udostępnienie niezmienionych metod obiektu obiekt zewnętrzny udostępnia pośrednio łącze IUnknown obiektu wewnętrznego obiekt zewnętrzny udostępnia bezpośrednio pozostałe łącza obiektu wewnętrznego

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 ; // licznik odniesień IUnknown *m_pUnkOuter ; // zewnętrzne IUnknown … } ;

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 ;

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) ; }

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

Emulacja i wersjonowanie HKEY_CLASSES_ROOT MyFirm.MyProg = this is current version of component CLSID = {a123x3y1-4ce6-4ce6-4ce6-2a212123223} CurVer = {a123x3y1-4ce6-4ce6-4ce6-2a212123223} MyFirm.MyProg.1= this is version 1 of component CLSID = {x000x0y0-4ce6-4ce6-4ce6-2a212123223} MyFirm.MyProg.2 = this is version 2 of component CLSID = {a123x3y1-4ce6-4ce6-4ce6-2a212123223} TreatAs = {y00000-4ce6-4ce6-4ce6-2a212123223} AutoTreatAs = {y00000-4ce6-4ce6-4ce6-2a212123223} funkcje: CoTreateAsClass

ActiveX Kontrolki, Serwery Kontrolki ActiveX: standard do rozszerzania zestawu pól dialogowych dostępnych w systemie Windows poprzednie standardy: Custom Controls, Visual Basic Controls OCX = ActiveX (OLE controls = ActiveX controls) gotowe komponenty funkcjonalne do budowania programów Server ActiveX: program udostępniający IDispatch

Realizacja interfejsu IDispatch 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) ; } ;

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

Private Sub Form_Load() Dim TitleArray As Variant Dim DataArray As Variant TitleArray = 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 = True End With With ThisChart .Type = Excel.Constants.xl3DColumn .HasLegend = False End With Command1_Click End Sub

Implementacja klienta automatyzacji – C++ CExcelApplication * app = new CExcelApplication(.....); //app-> Attach(....); App-> Workbooks.Add();

Dedykowany klient automatyzacji MFC/.Net potrafią wygenerować klasę udostępniającą funkcjonalność obiektu ActiveX na postawie: biblioteki TLB (również np. wkompilowanej w dll) zawartości rejestru (ID.klasy) klasa pośredniczy w wołaniu metod serwera dostępie do pól udostepnianych przez serwer (Get/Set) CMyComClassDriver c; c.CreateDispatch(ComObjectCLSID); x = c.Calculate(15); c.ReleaseDispatch();

Klient automatyzacji - 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) ;

IDispatch z perspektywy klienta Informacje o interfejsie ? IDispatch – samodokumentujacy się interfejs Biblioteka typów: Pliki .TLB Wbudowana w komponent (jako zasób) Sterowniki: VC++ - ClassWizard - dedykowana klasa (na podst. biblioteki typów) VB – import komponentu lub biblioteki

Właściwości interfejsu IDispatch Zalety: Samodokumentowanie się interfejsów Możliwość późnego wiązania Wady: Zła efektywność Praktyczne realizacje: Dwa zestawy interfejsów Interfejsy dualne (IDL: dual, HRESULT)

IDispatchEx Zmienione zestawy parametrów Dynamiczna zmiana udostępnianej funkcjonalności interface IDispatchEx: IDispatch { GetDispID(...); GetNextDispID(...); InvokeEx(...); DeleteMemberByName(...); DeleteMemberByDispID(...); GetMemberProperties(...); GetMemberName(...); GetNameSpaceParent(...); };

Obsługiwane typy danych IDL: boolean(bool), double, float, signed int(int/long), signed short(short), enum, BSTR, CY, DATE, IDispatch*, IUnknown*, SAFEARRAY, VARIANT

Variant struct tagVARIANT { union { struct __tagVARIANT { VARTYPE vt; // = VT_I4, VTUI1, VT_I2 ... WORD wReserved1, wReserved2, wReserved3; union { LONG lVal; // VT_I4 BYTE bVal; // VT_UI1 SHORT iVal; // VT_I2 FLOAT fltVal; // VT_R4 DOUBLE dblVal; // VT_R8 CY cyVal; // VT_CY DATE date; // VT_DATE BSTR bstrVal; // VT_BSTR IUnknown punkVal; // VT_UNKNOWN ....... } } };

Variant Funkcje usługowe: VariantChangeType(Ex) VariantClear VariantCopy VariantCopyInd VariantInit

BSTR Tablica znakowa (UNICODE) zakończona terminatorem i poprzedzona długością (przed miejscem określonym przez wskaźnik) VB, Java Funkcje usługowe C++: SysAllocString, SysAllocStringByteLen SysAllocStringLen SysFreeString SysReAllocString, SysReAllocStringLen SysStringByteLen, SysStringLen

SAFEARRAY typedef struct tagSAFEARRAY { USHORT cDims; // liczba wymiarów USHORT cFeatures; // znaczniki ULONG cbElements; // rozmiar elementu ULONG cLocks; // licznik rygli PVOID pvData; // dane tablicy SAFEARRAYBOUND rgsabound[]; // tablica dla każdego wymiaru } SAFEARRAY;

SAFEARRAY SafeArrayAllocData, SafeArrayAllocDescriptor, SafeArrayCreate(Ex), SafeArrayCreateVector(Ex), SafeArrayDestroy, SafeArrayDestroyData, SafeArrayDestroyDescriptor, SafeArrayAccesData, SafeArrayUnaccesData, SafeArrayLock, SafeArrayUnlock SafeArrayCopy, SafeArrayCopyData SafeArrayGetDim, SafeArrayRedim, SafeArrayPtrOfIndex, SafeArrayGetLBound, SafeArrayGetUBound, SafeArrayGetElement, SafeArrayGetElemsize SafeArrayPutElement, SafeGetVartype, SafeArrayGetIID, SafeArraySetIID SafeArrayGetRecordInfo, SafeArraySetRecordInfo

Refleksja Możliwość odpytywania o typ, metody i pola obiektów w czasie działania Mozliwość budowy wołań do metod w czasie działania Standardowy zestaw atrybutów odczytywalnych w czasie działania opisujących własności metod i pól (np. serializacja) Możliwość stosowania dodatkowych atrybutów (np. Informacji konfiguracyjnych)

COM wiecznie żywy

Runtime Callable Wrapper Współpraca z COM Runtime Callable Wrapper Natywny COM Server Klient .Net IUnknown IDispatch IFoo RCW jest generowany przez runtime

Współpraca z COM Object name klient COM Obiekt .Net IUnknown IDispatch IFoo IFoo Regasm.exe pozwala wygenerować GUID i zaktualizować wpisy w rejestrze.

Serwer Com w .NET Rejestracja: regasm.exe using System.Runtime.InteropServices; using System.Reflection; [GuidAttribute("EA5A0174-D303-459a-8B9B-28F6674E9371"), ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IKlasaN { uint SetState(int state); uint GetState(out int state); } [ClassInterface(ClassInterfaceType.None), GuidAttribute("493DEA38-15EB-4acf-8196-042CF32A29F3"), ComVisible(true), ProgId(„comtestnet.klasa.1”)] public class KlasaN: IKlasaN { ... Rejestracja: regasm.exe