Komponentowe systemy rozproszone COM i inni. Komunikacja/komponenty w WINDOWS w ujęciu historycznym 1. Schowek 2. DDE 3. 16-bitowe OLE 1.0 4. 16-bitowe.

Slides:



Advertisements
Podobne prezentacje
20041 Projektowanie dynamicznych witryn internetowych Paweł Górczyński ASP 3.0.
Advertisements

C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 4 ( ) Przeciążanie operatorów.
Deklaracje i definicje klas w C++ Składowe, pola, metody Konstruktory
Programowanie obiektowe
PSZ wykład 2 > Przegląd komponentów biblioteki VCL
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.
Obiektowe metody projektowania systemów Design Patterns STRATEGY.
Bezpieczeństwo wyjątków w C++: OpenGL
Systemy rozproszone W. Bartkiewicz
Systemy rozproszone W. Bartkiewicz
CORBA Łukasz Wnęk.
Programowanie obiektowe w Javie
CLR na platformie .NET Tomasz Kostarski.
COM Maciej Głowacki
Internet Communication Engine
Tworzenie ASP.NET Web Form
Systemy operacyjne Wykład nr 5: Wątki Piotr Bilski.
Biblioteki i przestrzenie nazw
C++ wykład 2 ( ) Klasy i obiekty.
Zasady zaliczenia Warunki uzyskania zaliczenia:
Wykład 8 Wojciech Pieprzyca
Enteprise Java Beans Emil Wcisło.
Wstęp do programowania obiektowego
Podstawy C# Grupa .NET PO.
Podstawy programowania II
Komponentowe systemy rozproszone
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
WPROWADZENIE W ŚWIAT OBIEKTÓW
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
Programowanie w języku C++
UML W V ISUAL S TUDIO Mateusz Lamparski. UML D EFINICJA Unified Modeling Language (UML) to graficzny język do obrazowania, specyfikowania, tworzenia i.
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.
Komponentowe systemy rozproszone Wprowadzenie. Komponent... jest to podstawowa jednostka oprogramowania z kontraktowo (deklaratywnie) opisanymi interfejsami,
Paweł Starzyk Obiektowe metody projektowania systemów
.NET i Bazy Danych Projekt: Wadim Grasza.
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 10 Programowanie w Windows 1.Aplikacja dialogowa (Dialog Based) PO10-1 / 26.
Partnerstwo dla Przyszłości 1 Lekcja 27 Klasy i obiekty.
Ł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.
Architektura Rafał Hryniów. Architektura Wizja projektu systemu, którą dzielą twórcy Struktura komponentów systemu, ich powiązań oraz zasad i reguł określających.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
Programowanie Obiektowe – Wykład 6
Wątki, programowanie współbieżne
(według:
Programowanie Obiektowe – Wykład 2
Aplikacje i usługi internetowe
Podstawy programowania
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 1. Schowek 2. DDE bitowe OLE bitowe OLE OLE 2.0 = COM = ActiveX (1996) bitowe OLE 7. Dcom 8. COM+ = COM + MTS + MSMQ (W2000)

Component Object Model Binarny standard komunikacji Nie jest językiem Nie wymaga konketnego języka Niezależny od języka Interfejsy – standard komunikacji Identyfikacja obiektów i usług (Pół)Automatyczne metody marszalingu danych Wspiera: enkapsulację, dziedziczenie interfejsu i implementacji, polimorfizm Elementy zarządzanie zasobami

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

In-proc serwer = DLL 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(); } Wywołania metod lokalnych serwer ładowany jest do przestrzeni procesu klienta

Local/Remote Server = EXE – marszaling danych między procesami- wymagane jest zarejestrowanie interfejsów 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(); } 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(); }

COM – identyfikacja klas GUID - globalnie unikalny identyfikator: 128-bitowa liczba np.: B77D61E0-47D8-11d0-B53F 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

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

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

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

Rejestracja COM-a ”ręczne” uruchomienie pliku typu.REG automatyczny import pliku.REG bezpośrednia manipulacja rejestrem obsługa /REGISTER i /UNREGISTER  90% błędów na początku to problemy z rejestracją np. katalogi debug/release

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

Tworzenie obiektów 1. Indywidualna funkcja tworzaca obiekty 2. 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 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 class ComClientClass {... virtual DoSmthg(int); } * pInterface;

Wsparcie dla COM Autorzy implementacji różnych języków definiją rozszerzenia pozwalające wołać COM-y. W C++ interfejs odpowiada wskaźnikowi do tablicy wskaźników do funkcji składowych interfejsu

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++ vs metody wirtualne

Skrypt IDL Język opisu interfejsów [uuid(108dbc1b-1ad2-4bda-b45a-e6b0f014c3a1),object] interface IMKInterface : IUnknown { import "unknwn.idl"; HRESULT GetSound([out]WORD *dw); HRESULT SetSound([in] WORD dw); HRESULT Beep (); } 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-2a } = My Prog ProgID = Producent.Serwer.Wersja TypeLib = {a123x3y1-4ce6-4ce6-4ce6-a } TypeLib {a123x3y1-4ce6-4ce6-4ce6-a } = My Type Lib Dir = c:\tmp HelpDir = c:\tmp\Help 1.00 = Any.TLB 9 = English.TLB

IUnknown - podstawowy interfejs obiektu każdy obiekt COM odostępnia interfejs IUnknown każdy interfejs COM 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++ (MFC) 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

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

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

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 CoGetClassObject ReadRegistry CoLoadLibrary(“test.dll”,TRUE) Hmodule = LoadLiibrary(test.dll) GetProcAdress(hModule, ”DllGetClassObject”) DllGetClassObject pFactory->CreateInstance pFactory->Release DllGetClassObject pFactory->AddRef pFactory->QueryInterface pFactory-> CreateInstance pObject->QueryInterface pObject->AddRef DllMain CLSID { } InprocServer32 = “test.dll”

Serwer lokalny program wykonywalny (EXE) 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)) ) … // błąd inicjalizacji // zakończenie CoRevokeClassObject (dwReg) ; pClassFact->Release () ; CoUninitializeEx () ;

Implementacja wielu interfejsów COM przez jedną klasę C++? Podział odpowiedzialności – różne klasy C++ Techniczny problem w przypadku realizacji interfejsów jako oddzielnych klas pot. problem z powoływaniem do życia i zarządzaniem wieloma POWIĄZANYMI obiektami Adres interfejsu vs. tożsamość obiektu możliwe rozwiązanie: klasy zagnieżdzone metody z IUnknown są delegowne do obiektu głównego MFC – BEGIN/END_INTERFACE_PART

COM - REUSABILITY

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-2a } CurVer = {a123x3y1-4ce6-4ce6-4ce6-2a } MyFirm.MyProg.1= this is version 1 of component CLSID = {x000x0y0-4ce6-4ce6-4ce6-2a } MyFirm.MyProg.2 = this is version 2 of component CLSID = {a123x3y1-4ce6-4ce6-4ce6-2a } TreatAs = {y ce6-4ce6-4ce6-2a } AutoTreatAs = {y ce6-4ce6-4ce6-2a } funkcje: CoTreateAsClass

ACTIVE X

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

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

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

Klient automatyzacji - Visual Basic Dim ThisExcel As Excel.Application Dim ThisChart As Excel.Chart …. 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

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:  Duży narzut na pojedyncze wołanie Techniczna realizacje ActiveX:  Dwa zestawy interfejsów (dla COM/ActiveX)  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(...); };

COM VS.NET Com wiecznie żywy

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

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

Klient Com w.NET Import i generacja wrapera Visual Studio Type Library Importer (Tlbimp.exe) System.Runtime.InteropServices.TypeLib Converter class “Ręcznie” napisana klasa Managed C++

Serwer Com w.NET using System.Runtime.InteropServices; using System.Reflection; [GuidAttribute("EA5A0174-D a-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 CF32A29F3"), ComVisible(true), ProgId(„comtestnet.klasa.1”)] public class KlasaN: IKlasaN {... } Rejestracja: regasm.exe