09 com fundamentals1

Upload: sirotnikov

Post on 02-Jun-2018

228 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/10/2019 09 COM Fundamentals1

    1/49

    FundamentalsFundamentalsOf COM(+)Of COM(+)

    (Part 1)(Part 1)

    Don BoxDon BoxCofounder Cofounder

    DevelopMentor DevelopMentor http://http:// www.develop.com/dboxwww.develop.com/dbox

    1111 --203203

  • 8/10/2019 09 COM Fundamentals1

    2/49

    COMCOM The IdeaThe IdeaCOM is based on three fundamental ideasCOM is based on three fundamental ideas

    Clients program in terms of interfaces,Clients program in terms of interfaces,not classesnot classesImplementation code is not statically linked,Implementation code is not statically linked,

    but rather loaded onbut rather loaded on --demand at runtimedemand at runtimeObjectObject implementorsimplementors declare their runtimedeclare their runtimerequirements and the system ensures thatrequirements and the system ensures thatthese requirements are metthese requirements are metThe former two are the core of classic COMThe former two are the core of classic COMThe latter is the core of MTS and COM+The latter is the core of MTS and COM+

  • 8/10/2019 09 COM Fundamentals1

    3/49

    Tale Of TwoTale Of Two COMsCOMsCOM is used primarily for two tasksCOM is used primarily for two tasksTask 1: Gluing together multiple components insideTask 1: Gluing together multiple components insidea processa process

    Class loading, type information, etcClass loading, type information, etc

    Task 2: Inter Task 2: Inter --process/Inter process/Inter --host communicationshost communications

    ObjectObject --based Remote Procedure Calls (ORPC)based Remote Procedure Calls (ORPC)Pros: Same programming model and APIs used forPros: Same programming model and APIs used forboth tasksboth tasksCons: Same programming model and APIs used forCons: Same programming model and APIs used forboth tasksboth tasksDesign around the task at handDesign around the task at hand

  • 8/10/2019 09 COM Fundamentals1

    4/49

    MotivationMotivationWe want to build dynamicallyWe want to build dynamically composablecomposable systemssystems

    Not all parts of application are statically linkedNot all parts of application are statically linked

    We want to minimize coupling within the systemWe want to minimize coupling within the systemOne change propagates to entire source code treeOne change propagates to entire source code tree

    We want plugWe want plug --andand --playplay replaceablityreplaceablity andand

    extensibilityextensibilityNew pieces should be indistinguishable from old,New pieces should be indistinguishable from old,known partsknown parts

    We want freedom from file/path dependenciesWe want freedom from file/path dependenciesxcopyxcopy /s *. /s *. dlldll C:C: \ \winntwinnt \ \ system32 not a solutionsystem32 not a solution

    We want components with different runtimeWe want components with different runtimerequirements to live peaceably together requirements to live peaceably together

    Need to mix heterogeneous objects in a single processNeed to mix heterogeneous objects in a single process

  • 8/10/2019 09 COM Fundamentals1

    5/49

    A SolutionA Solution ComponentsComponentsCircaCirca --19801980 s style objects style object --orientation based onorientation based onclasses and objectsclasses and objects

    Classes used for object implementationClasses used for object implementationClasses also used for consumer/client type hierarchyClasses also used for consumer/client type hierarchy

    Using classUsing class --based OO introduces nonbased OO introduces non --trivialtrivialcoupling between client and objectcoupling between client and object

    Client assumes complete knowledge of public interfaceClient assumes complete knowledge of public interfaceClient may know even more under certain languagesClient may know even more under certain languages(e.g., C++)(e.g., C++)

    CircaCirca --19901990 s object orientation separates clients object orientation separates client --visible type system from objectvisible type system from object --visiblevisibleimplementationimplementation

    Allows client to program in terms of abstract typesAllows client to program in terms of abstract types

    When done properly, completely hides implementationWhen done properly, completely hides implementationclass from clientclass from client

  • 8/10/2019 09 COM Fundamentals1

    6/49

    // faststring.h/ faststring.h seen by client and objecteen by client and object implementormplementorclasslass FastStringastString {

    char *har * m_psz_psz ;

    public:ublic:FastString(const char *astString(const char * pszsz );;~FastString();FastString();int Length() const;nt Length() const;int Find(const char *nt Find(const char * pszSearchStringszSearchString ) const;const;

    };;

    /// faststring.cppaststring.cpp seen by objecteen by object implementormplementor onlynlyFastString::FastString(constastString::FastString(const char *har * pszsz )

    : : : : :

    Recall: ClassRecall: Class --BasedBased ooooThe objectThe object implementor implementor defines a class thatdefines a class that

    Is used to produce new objectsIs used to produce new objectsIs used by the client to instantiate and invoke methodsIs used by the client to instantiate and invoke methods

  • 8/10/2019 09 COM Fundamentals1

    7/49

    Recall: ClassRecall: Class --BasedBased ooooClient expected to import full definition of classClient expected to import full definition of class

    Includes complete public signature at time of compilationIncludes complete public signature at time of compilationAlso includes size/offset information under C++Also includes size/offset information under C++

    /// client.cpplient.cpp// import type definitions to use object/ import type definitions to use object

    #includeinclude

    faststring.haststring.h

    intnt FindTheOffsetindTheOffset ( ) { ) {intnt i == -1;;FastStringastString *pfsfs = newnew FastString(astString( Helloello , WorldWorld ); ;if (f ( pfsfs ) { {

    i == pfsfs ->Find(Find( o, W, W ); ;deleteelete pfsfs ;}return i;eturn i;

    }

  • 8/10/2019 09 COM Fundamentals1

    8/49

    ClassClass --Based OO PitfallsBased OO PitfallsClasses notClasses not soso bad when the world is statically linkedbad when the world is statically linked

    Changes to class and client happen simultaneouslyChanges to class and client happen simultaneouslyProblematic if existing public interface changesProblematic if existing public interface changes

    Most environments do a poor job at distinguishingMost environments do a poor job at distinguishingchanges to public interface from private detailschanges to public interface from private details

    Touching private members usually triggers cascading rebuildTouching private members usually triggers cascading rebuild

    Static linking has many drawbacksStatic linking has many drawbacksCode size bigger Code size bigger CanCan t replace class code independentlyt replace class code independently

    Open Question:Open Question: Can classes be dynamically linked?Can classes be dynamically linked?

  • 8/10/2019 09 COM Fundamentals1

    9/49

    // faststring.h/ faststring.h

    classlass __declspec(dllexport)_declspec(dllexport) FastStringastString {char *har * m_psz_psz ;

    public:ublic:

    FastString(const char *astString(const char * pszsz );;~FastString();FastString();int Length() const;nt Length() const;int Find(const char *nt Find(const char * pszSearchStringszSearchString ) const;const;

    };;

    Classes Versus Dynamic LinkingClasses Versus Dynamic Linking

    Most compilers offer a compiler keyword orMost compilers offer a compiler keyword ordirective to export all class members from DLLdirective to export all class members from DLL

    Results in mechanical change at build/runResults in mechanical change at build/run --timetimeRequires zero change to source code (except introducingRequires zero change to source code (except introducingthe directive)the directive)

  • 8/10/2019 09 COM Fundamentals1

    10/49

    Classes Versus Dynamic LinkingClasses Versus Dynamic Linking

    Client AClient AClients statically link toClients statically link toimport libraryimport library

    Maps symbolic name to DLLMaps symbolic name to DLLand entry nameand entry name

    Client imports resolved atClient imports resolved atload timeload timeNote: C++ compilers nonNote: C++ compilers non --standardstandard wrtwrt DLLsDLLs

    DLL and clients must be builtDLL and clients must be builtusing same compiler/linker using same compiler/linker

    Client BClient B

    Client CClient C

    faststring.dllfaststring.dll

    import namemport name file nameile name export namexport name

    ??@3fFastString_6Length?@3fFastString_6Length??@3fFastString_4Find?@3fFastString_4Find??@3fFastString_ctor@sz2?@3fFastString_ctor@sz2??@3fFastString_dtor?@3fFastString_dtor

    faststring.dllaststring.dllfaststring.dllaststring.dllfaststring.dllaststring.dllfaststring.dllaststring.dll

    ??@3fFastString_6Length?@3fFastString_6Length??@3fFastString_4Find?@3fFastString_4Find??@3fFastString_ctor@sz2?@3fFastString_ctor@sz2??@3fFastString_dtor?@3fFastString_dtor

    faststring.lib

  • 8/10/2019 09 COM Fundamentals1

    11/49

    // faststring.h/ faststring.hclass FastString {lass FastString {

    char *har * m_psz_psz ;public:ublic:

    FastString(const char *astString(const char * pszsz );;~FastString();FastString();int Length() const;nt Length() const;int Find(const char *nt Find(const char * pszSearchStringszSearchString ) const;const;

    };;

    // faststring.cpp/ faststring.cpp#includeinclude faststring.haststring.h #include include

    int FastString::Length() const {nt FastString::Length() const {returneturn strlen(m_psztrlen(m_psz );;

    }

    Classes Versus DynamicClasses Versus DynamicLinking: EvolutionLinking: Evolution

    Challenge: Improve the performance of Length!Challenge: Improve the performance of Length!Do not change publicDo not change publicinterface and breakinterface and breakencapsulationencapsulation

  • 8/10/2019 09 COM Fundamentals1

    12/49

    class __declspec(dllexport) FastStringlass __declspec(dllexport) FastString{

    char *har * m_psz_psz ;intnt m_cch_cch ;public:ublic:

    FastString(const char *astString(const char * pszsz );;~FastString();FastString();

    int Length() const;nt Length() const;int Find(const char *nt Find(const char * pszSSszSS ) const;const;

    };;

    FastString::FastString(const char *sz)astString::FastString(const char *sz): m_psz(new_psz(new char[strlen(sz)+1]),har[strlen(sz)+1]),

    m_cch(strlen(sz_cch(strlen(sz )) {) {

    strcpy(m_psztrcpy(m_psz , sz); sz);}

    int FastString::Length() const {nt FastString::Length() const {returneturn m_cch_cch ;

    }

    Classes Versus DynamicClasses Versus DynamicLinking: EvolutionLinking: Evolution

    Solution: Speed up FastString::Length by cachingSolution: Speed up FastString::Length by cachinglength as data member length as data member

  • 8/10/2019 09 COM Fundamentals1

    13/49

    Client AClient A

    Client BClient B

    Client CClient C

    faststring.dllfaststring.dll

    sizeofsizeof ==8==8

    sizeofsizeof ==8==8sizeofsizeof ==4==4

    sizeofsizeof ==4==4

    Classes Versus DynamicClasses Versus DynamicLinking: EvolutionLinking: Evolution

    New DLL assumesNew DLL assumessizeof(FastStringsizeof(FastString ) is 8) is 8Existing Clients assumeExisting Clients assumesizeof(FastStringsizeof(FastString ) is 4) is 4Clients that want newClients that want new

    functionality recompilefunctionality recompileOld Clients break!Old Clients break!This is an inherentThis is an inherentlimitation of virtually alllimitation of virtually all

    C++ environmentsC++ environments

  • 8/10/2019 09 COM Fundamentals1

    14/49

    Client AClient A(v2)(v2)

    faststring.dllfaststring.dll(v1)(v1)

    FastString::FastStringFastString::FastStringFastString::~FastStringFastString::~FastStringFastString::LengthFastString::LengthFastString::FindFastString::Find

    FastString::FastStringFastString::FastStringFastString::~FastStringFastString::~FastString

    FastString::LengthFastString::LengthFastString::FindFastString::Find

    FastString::FindNFastString::FindN

    Classes Versus DynamicClasses Versus DynamicLinking: Interface EvolutionLinking: Interface Evolution

    Adding new public methods OK when statically linkedAdding new public methods OK when statically linkedClass and client code inseparableClass and client code inseparable

    Adding public methods to a DLLAdding public methods to a DLL --based class dangerous!based class dangerous!New client expects method to be thereNew client expects method to be thereOld DLLs have never heard of this method!!Old DLLs have never heard of this method!!

  • 8/10/2019 09 COM Fundamentals1

    15/49

    ConclusionsConclusions

    Cannot change definition of a dataCannot change definition of a data

    type without massivetype without massiverebuild/redeployment of client/objectrebuild/redeployment of client/objectIf clients program in terms of classes,If clients program in terms of classes,

    then classes cannot change in anythen classes cannot change in anymeaningful waymeaningful wayClasses must change because weClasses must change because wecancan t get it right the first timet get it right the first timeSolution: Clients must not programSolution: Clients must not programin terms of classesin terms of classes

  • 8/10/2019 09 COM Fundamentals1

    16/49

    InterfaceInterface

    --BasedBased

    ProgrammingProgrammingKey to solving the replaceable component problem isKey to solving the replaceable component problem isto split the world into twoto split the world into twoThe types the client programs against can neverThe types the client programs against can neverchangechange

    Since classes need to change, these better not be classes!Since classes need to change, these better not be classes!Solution based on defining alternative type systemSolution based on defining alternative type systembased on abstract types called interfacesbased on abstract types called interfacesAllowing client to only see interfaces insulates clientsAllowing client to only see interfaces insulates clientsfrom changes to underlying class hierarchyfrom changes to underlying class hierarchyMost common C++ technique for bridging interfacesMost common C++ technique for bridging interfacesand classes is to use abstract baseand classes is to use abstract baseclasses as interfacesclasses as interfaces

  • 8/10/2019 09 COM Fundamentals1

    17/49

    Abstract Bases AsAbstract Bases AsInterfacesInterfaces

    A class can be designated as abstract by makingA class can be designated as abstract by making(at least) one method(at least) one method pure virtualpure virtual

    structstruct IFastStringIFastString {{virtualvirtual intint Length( ) const = 0;Length( ) const = 0;virtualvirtual intint Find(const char *) const = 0;Find(const char *) const = 0;

    };};

    Cannot instantiate abstract baseCannot instantiate abstract baseCan declare pointers or references to abstract basesCan declare pointers or references to abstract bases

    Must instead derive concrete type that implementsMust instead derive concrete type that implementseach pure virtual functioneach pure virtual functionClasses withClasses with onlyonly pure virtual functions (no datapure virtual functions (no datamembers, no implementation code) often calledmembers, no implementation code) often called

    pure abstract bases, protocol classespure abstract bases, protocol classes oror interfacesinterfaces

  • 8/10/2019 09 COM Fundamentals1

    18/49

    Interfaces AndInterfaces AndImplementationsImplementations

    Given an abstract interface, the most common wayGiven an abstract interface, the most common wayto associate an implementation with it isto associate an implementation with it isthrough inheritancethrough inheritance

    ClassClass FastStringFastString : public: public IFastStringIFastString {...};{...};

    Implementation type must provide concreteImplementation type must provide concreteimplementations of each interface methodimplementations of each interface methodSome mechanism needed to create instances of theSome mechanism needed to create instances of theimplementation type without exposing layoutimplementation type without exposing layout

    Usually takes the form of a creator or factory functionUsually takes the form of a creator or factory functionMust provide client with a way to delete objectMust provide client with a way to delete object

    Since the new operator is not used by the client, it cannotSince the new operator is not used by the client, it cannotcall the delete operator call the delete operator

  • 8/10/2019 09 COM Fundamentals1

    19/49

    Exporting Via Abstract BasesExporting Via Abstract Bases

    /// faststringclient.haststringclient.h common header between client/classommon header between client/class

    // here/ here s the DLL the DLL -friendly abstract interface:riendly abstract interface:structtruct IFastStringFastString {

    virtual voidirtual void Deleteelete () = 0;) = 0;virtual int Length() const = 0;irtual int Length() const = 0;virtual int Find(const char *sz) const = 0;irtual int Find(const char *sz) const = 0;

    };;

    // and here/ and here s the DLL the DLL -friendly factory function:riendly factory function:externxtern C booloolCreateInstancereateInstance (constconst char *har * pszClassNameszClassName , // which class? // which class?

    const char *onst char * pszsz , // // ctortor argsrgsIFastStringFastString *** ppfspfs ); // the; // the objrefbjref

  • 8/10/2019 09 COM Fundamentals1

    20/49

    Exporting Via Abstract BasesExporting Via Abstract Bases// faststring.h/ faststring.h private source file of classrivate source file of class#includeinclude faststringclient.haststringclient.h class FastString : publiclass FastString : public IFastStringFastString {// normal prototype of/ normal prototype of FastStringastString class + Deletelass + Delete

    void Delete() {oid Delete() { deleteelete this; }his; }};;

    /// component.cppomponent.cpp private source file for entire DLLrivate source file for entire DLL#includeinclude faststring.haststring.h // import/ import FastStringastString#includeinclude fasterstring.hasterstring.h // import/ import FasterStringasterString (another class)another class)

    boolool CreateInstance(constreateInstance(const char *har * pszClassNameszClassName ,const char *onst char * pszsz , IFastStringFastString *** ppfspfs ) { {

    *ppfspfs = 0; 0;

    if (f ( strcmp(pszClassNametrcmp(pszClassName , FastStringastString ) == 0)== 0)*ppfspfs = static_cast< static_cast< IFastStringFastString *>(>( newew FastString(szastString(sz )););

    else if (lse if ( strcmp(pszClassNametrcmp(pszClassName , FasterStringasterString ) == 0)== 0)*ppfspfs = static_cast< static_cast< IFastStringFastString *>(>( newew FasterString(szasterString(sz )););

    return *eturn * ppfspfs = 0;= 0;}

  • 8/10/2019 09 COM Fundamentals1

    21/49

    m_text m_text

    m_lengthm_length

    vptrvptr FastString::DeleteFastString::Delete

    FastString::LengthFastString::Length

    FastString::FindFastString::Find

    pfspfs

    ClientClient ObjectObject

    Exporting UsingExporting UsingAbstract BasesAbstract Bases

  • 8/10/2019 09 COM Fundamentals1

    22/49

    boolool LoadAndCreate(constoadAndCreate(const char *har * szDLLzDLL, const char *sz, const char *sz,IFastStringFastString *** ppfspfs ){{

    HINSTANCE h =INSTANCE h = LoadLibrary(szDLLoadLibrary(szDLL );;

    boolool (** fp)(constp)(const char*, const char*,har*, const char*, IFastStringFastString **);*);*((FARPROC*)&((FARPROC*)& fpp ) == GetProcAddress(hetProcAddress(h , CreateInstancereateInstance ); ;returneturn fp(p( FastStringastString , sz z , ppfspfs );;

    }

    Interfaces AndInterfaces AndPlugPlug --compatibilitycompatibility

    Note that a particular DLL can supply multiple implementationsNote that a particular DLL can supply multiple implementationsof same interfaceof same interface

    CreateInstance(CreateInstance( SlowStringSlowString ,, Hello!!Hello!! , &, &pfspfs ););

    Due to simplicity of model, runtime selection of Due to simplicity of model, runtime selection of implementation trivialimplementation trivial

    Explicitly load DLL and bind function addressExplicitly load DLL and bind function address

  • 8/10/2019 09 COM Fundamentals1

    23/49

    Interfaces And EvolutionInterfaces And EvolutionPrevious slides alluded to interface remainingPrevious slides alluded to interface remainingconstant across versionsconstant across versions

    InterfaceInterface --based development mandates that newbased development mandates that newfunctionality be exposed using additional interfacefunctionality be exposed using additional interface

    Extended functionality provided by deriving fromExtended functionality provided by deriving fromexisting interfaceexisting interface

    Orthogonal functionality provided by creating newOrthogonal functionality provided by creating newsibling interfacesibling interface

    Some technique needed for dynamicallySome technique needed for dynamicallyinterrogating an object for interface supportinterrogating an object for interface support

    Most languages support some sort of runtime castMost languages support some sort of runtime castoperation (e.g., C++operation (e.g., C++ s dynamic_cast)s dynamic_cast)

  • 8/10/2019 09 COM Fundamentals1

    24/49

    /// faststringclient.haststringclient.hstructtruct IFastNFindFastNFind : public IFastString { public IFastString {

    virtual int FindN(const char *irtual int FindN(const char * szz , int n) const = 0; int n) const = 0;

    };; /// faststringclient.cxxaststringclient.cxx

    int Find10thInstanceOfFoo(IFastString *nt Find10thInstanceOfFoo(IFastString * pfsfs ) { {IFastNFindFastNFind *pfnffnf = 0; 0;

    if (f ( pfnffnf = dynamic_cast>(pfsfs )) {) {returneturn pfnffnf ->FindN(indN( Foooo , 10); 10);}elselse

    // implement by hand.../ implement by hand...

    }

    Example: AddingExample: AddingExtended FunctionalityExtended Functionality

    Add method to find the nth instance of szAdd method to find the nth instance of sz

  • 8/10/2019 09 COM Fundamentals1

    25/49

    m_textm_text

    m_lengthm_length

    vptr vptr

    FastString::DeleteFastString::Delete

    FastString::LengthFastString::Length

    FastString::FindFastString::Find

    pfspfs

    ClientClient ObjectObject

    pfnf pfnf FastString::FindNFastString::FindN

    Example: AddingExample: AddingExtended FunctionalityExtended Functionality

  • 8/10/2019 09 COM Fundamentals1

    26/49

    /// faststringclient.haststringclient.hstructtruct IPersistentObjectPersistentObject {

    virtual void Delete(void) = 0;irtual void Delete(void) = 0;virtualirtual boolool Load(const char *oad(const char * szz ) = 0; = 0;virtualirtual boolool Save(const char *ave(const char * szz ) const = 0; const = 0;

    };;

    /// faststringclient.cxxaststringclient.cxx

    boolool SaveString(IFastStringaveString(IFastString *pfsfs ) { {

    IPersistentObjectPersistentObject *ppopo = 0; 0;if (f ( ppopo = dynamic_cast>(pfsfs )) {) {

    returneturn ppopo ->Save(Save( Autoexec.batutoexec.bat ); ;}elselse

    return false; // cannot save...eturn false; // cannot save...

    }

    Example: AddingExample: AddingOrthogonal FunctionalityOrthogonal Functionality

    Add support for generic persistenceAdd support for generic persistence

  • 8/10/2019 09 COM Fundamentals1

    27/49

    m_textm_text

    m_lengthm_length

    vptrvptrFastString::DeleteFastString::DeleteFastString::LengthFastString::Length

    FastString::FindFastString::Find

    pfspfs

    Client Object

    vptrvptr

    FastString::DeleteFastString::DeleteFastString::LoadFastString::Load

    ppoppo

    FastString::SaveFastString::Save

    Example: AddingExample: AddingOrthogonal FunctionalityOrthogonal Functionality

  • 8/10/2019 09 COM Fundamentals1

    28/49

    Fixing InterfaceFixing Interface --BasedBasedProgramming In C++Programming In C++

    The dynamic_cast operator has several problemsThe dynamic_cast operator has several problemsthat must be addressedthat must be addressed

    1) Its implementation is non1) Its implementation is non --standard across compilersstandard across compilers2) There is no standard runtime representation2) There is no standard runtime representationfor thefor the typenametypename3) Two parties may choose colliding3) Two parties may choose colliding typenamestypenames

    Can solve #1 by adding yet another wellCan solve #1 by adding yet another well --knownknownabstract method to each interface (a la Delete)abstract method to each interface (a la Delete)

    #2 and #3 solved by using a well#2 and #3 solved by using a well --knownknownnamespace/type format for identifying interfacesnamespace/type format for identifying interfacesUUIDsUUIDs from OSF DCE are compact (128 bit), efficient andfrom OSF DCE are compact (128 bit), efficient andguarantee uniquenessguarantee uniqueness

    UUIDsUUIDs are basically big, unique integers!are basically big, unique integers!

  • 8/10/2019 09 COM Fundamentals1

    29/49

    QueryInterfaceQueryInterfaceCOM programmers use the wellCOM programmers use the well --known abstractknown abstractmethod (method ( QueryInterfaceQueryInterface ) in lieu of dynamic_cast) in lieu of dynamic_cast

    virtual HRESULT _ virtual HRESULT _ stdcallstdcallQueryInterface(REFIIDQueryInterface(REFIID riidriid ,// the requested UUID,// the requested UUIDvoid **void ** ppvppv // the resultant // the resultant objref objref ) = 0;) = 0;

    Returns status code indicating success (S_OK) orReturns status code indicating success (S_OK) orfailure (E_NOINTERFACE)failure (E_NOINTERFACE)UUID is integral part of interface definitionUUID is integral part of interface definition

    Defined as a variable with IID_ prefixed to type nameDefined as a variable with IID_ prefixed to type nameVCVC--specific __ specific __ declspec(uuiddeclspec(uuid ) conjoins COM/C++ names) conjoins COM/C++ names

  • 8/10/2019 09 COM Fundamentals1

    30/49

    voidoid UseAsTelephone(ICalculatorseAsTelephone(ICalculator *pCalcCalc ) { {ITelephoneTelephone *pPhonePhone = 0; 0;pPhonePhone = dynamic_cast< dynamic_cast< ITelephoneTelephone *>(>( pCalcCalc );;if (f ( pPhonePhone ) { {

    // use/ use pPhonePhone

    : : : : :

    voidoid UseAsTelephone(ICalculatorseAsTelephone(ICalculator *pCalcCalc ) { {ITelephoneTelephone *pPhonePhone = 0; 0;

    HRESULT hr =RESULT hr = pCalcCalc ->QueryInterface(IID_ITelephoneueryInterface(IID_ITelephone ,(void**)&void**)& pPhonePhone );;

    if (hr == S_OK) {f (hr == S_OK) {// use/ use pPhonePhone

    : : : : :

    QueryInterfaceQueryInterface As A BetterAs A BetterDynamic CastDynamic Cast

  • 8/10/2019 09 COM Fundamentals1

    31/49

    ICalculatorCalculator *pCalc1 =pCalc1 = CreateCalcreateCalc (););ITelephoneTelephone *pPhone1 =pPhone1 = CreatePhonereatePhone (););ICalculatorCalculator *pCalc2 = dynamic_cast(pPhone1);>(pPhone1);ICalculatorCalculator *pCalc3 =pCalc3 = CreateCalcreateCalc (););

    pPhone1Phone1 ->Dial(pCalc1Dial(pCalc1 ->Add(pCalc2Add(pCalc2 ->Add(pCalc3Add(pCalc3 ->Add(2))));Add(2))));

    pCalc1Calc1 ->Delete(); // assume interfaces have DeleteDelete(); // assume interfaces have DeletepCalc2Calc2 ->Delete(); // per earlier discussionDelete(); // per earlier discussionpPhone1Phone1 ->Delete();Delete();

    Fixing InterfaceFixing Interface --BasedBasedProgramming In C++Programming In C++

    Previous examples used aPrevious examples used a DeleteDelete method to allowmethod to allowclient to destroy objectclient to destroy object

    Requires client to remember which references point toRequires client to remember which references point towhich objects to ensure each object deleted exactly oncewhich objects to ensure each object deleted exactly once

  • 8/10/2019 09 COM Fundamentals1

    32/49

    Fixing InterfaceFixing Interface --BasedBasedProgramming In C++Programming In C++

    COM solves theCOM solves the DeleteDelete problem withproblem withreference countingreference counting

    Clients blindlyClients blindly DeleteDelete each reference, not each objecteach reference, not each object

    Objects can track number of extant references andObjects can track number of extant references and

    autoauto --delete when count reaches zerodelete when count reaches zeroRequires 100% compliance with ref. counting rulesRequires 100% compliance with ref. counting rulesAll operations that return interface pointers mustAll operations that return interface pointers mustincrement the interface pointer increment the interface pointer s reference counts reference count

    QueryInterfaceQueryInterface ,, CreateInstanceCreateInstance , etc., etc.Clients must inform object that a particular interfaceClients must inform object that a particular interfacepointer has been destroyed using wellpointer has been destroyed using well --known methodknown method

    Virtual ULONG _ Virtual ULONG _ stdcallstdcall Release( ) = 0;Release( ) = 0;

  • 8/10/2019 09 COM Fundamentals1

    33/49

    ICalculatorCalculator *pCalc1 =pCalc1 = CreateCalcreateCalc (););ITelephoneTelephone *pPhone1 =pPhone1 = CreatePhonereatePhone (););

    ICalculatorCalculator *pCalc2 = 0;pCalc2 = 0;ICalculatorCalculator *pCalc3 =pCalc3 = CreateCalcreateCalc (););ITelephoneTelephone *pPhone2 = 0;pPhone2 = 0;ICalculatorCalculator *pCalc4 = 0;pCalc4 = 0;

    pPhone1Phone1 ->QueryInterface(IID_ICalculator,(voidueryInterface(IID_ICalculator,(void **)&pCalc2);*)&pCalc2);pCalc3Calc3 ->QueryInterface(IID_ITelephone,(voidueryInterface(IID_ITelephone,(void **)&pPhone2);*)&pPhone2);pCalc1Calc1 ->QueryInterface(IID_ICalculatorueryInterface(IID_ICalculator , (void**)&pCalc4); (void**)&pCalc4);

    pPhone1Phone1 ->Dial(pCalc1Dial(pCalc1 ->Add(pCalc2Add(pCalc2 ->Add(pCalc3Add(pCalc3 ->Add(2))));Add(2))));

    pCalc1Calc1 ->Release(); pCalc4Release(); pCalc4 ->Release();Release();pCalc2Calc2 ->Release(); pPhone1Release(); pPhone1 ->Release();Release();

    pCalc3Calc3 ->Release(); pPhone2Release(); pPhone2 ->Release();Release();

    Reference Counting BasicsReference Counting Basics

  • 8/10/2019 09 COM Fundamentals1

    34/49

    extern const IIDxtern const IID IID_IUnknownID_IUnknown ;structtruct IUnknownUnknown {

    virtual HRESULT STDMETHODCALLTYPEirtual HRESULT STDMETHODCALLTYPE QueryInterfaceueryInterface (const IID&onst IID& riidiid , void ** void ** ppvpv ) = 0; = 0;

    virtual ULONG STDMETHODCALLTYPEirtual ULONG STDMETHODCALLTYPE AddRefddRef ( ) = 0; ) = 0;virtual ULONG STDMETHODCALLTYPE Release( ) = 0;irtual ULONG STDMETHODCALLTYPE Release( ) = 0;

    };;

    IUnknownIUnknownThe three core abstract operations (The three core abstract operations ( QueryInterfaceQueryInterface ,,AddRef AddRef , and Release) comprise the core interface, and Release) comprise the core interface

    of COM,of COM, IUnknownIUnknownAll COM interfaces must extendAll COM interfaces must extend IUnknownIUnknownAll COM objects must implementAll COM objects must implement IUnknownIUnknown

  • 8/10/2019 09 COM Fundamentals1

    35/49

  • 8/10/2019 09 COM Fundamentals1

    36/49

    Com Interfaces In NatureCom Interfaces In Nature

    COM interfaces are described first inCOM interfaces are described first inCOM IDLCOM IDLCOM IDL is an extension to DCE IDLCOM IDL is an extension to DCE IDL

    Support for objects + various wire optimizationsSupport for objects + various wire optimizations

    IDL compiler directly emits C/C++ interfaceIDL compiler directly emits C/C++ interfacedefinitions as source codedefinitions as source codeIDL compiler emits tokenized type libraryIDL compiler emits tokenized type librarycontaining (most) of original contents in ancontaining (most) of original contents in aneasily parsed formateasily parsed formatJavaJava /Visual Basic /Visual Basic pick up mappings frompick up mappings fromtype librarytype library

  • 8/10/2019 09 COM Fundamentals1

    37/49

    Foo.idlFoo.idl IDL IDL

    DescriptionDescriptionofof FooFoo interfacesinterfacesand datatypesand datatypes

    Foo.hFoo.hC/C++C/C++

    DefinitionsDefinitions

    Foo_i.cFoo_i.cGUIDsGUIDs

    Foo_p.cFoo_p.cProxy/StubProxy/Stub

    dlldata.cdlldata.cClass LoadingClass Loading

    Support Support

    Foo.tlbFoo.tlbBinaryBinaryDescriptionsDescriptions

    MIDL.EXEMIDL.EXE *.java*.java Java JavaDefinitionsDefinitions

    JACTIVEX.EXEJACTIVEX.EXE

    COM IDLCOM IDL

  • 8/10/2019 09 COM Fundamentals1

    38/49

    COM IDLCOM IDLAll elements in an IDL file can have attributesAll elements in an IDL file can have attributes

    Appear in [ ] prior to subject of attributesAppear in [ ] prior to subject of attributes

    Interfaces are defined at global scopeInterfaces are defined at global scopeRequired by MIDL to emit networking codeRequired by MIDL to emit networking code

    Must refer to exported types inside library blockMust refer to exported types inside library block

    Required by MIDL to emit type library definitionRequired by MIDL to emit type library definitionCan import std interface suiteCan import std interface suite

    WTYPES.IDLWTYPES.IDL -- basic data typesbasic data typesUNKNWN.IDLUNKNWN.IDL -- core type interfacescore type interfaces

    OBJIDL.IDLOBJIDL.IDL -- core infrastructurecore infrastructure itfsitfsOLEIDL.IDLOLEIDL.IDL -- OLEOLE itfsitfsOAIDL.IDLOAIDL.IDL -- AutomationAutomation itfsitfsOCIDL.IDLOCIDL.IDL -- ActiveX ControlActiveX Control itfsitfs

  • 8/10/2019 09 COM Fundamentals1

    39/49

    [ uuid(DEFACED1 uuid(DEFACED1 -0229229 -2552552 -1D11D11 -ABBADABBAD00), object ]BBADABBAD00), object ]interfacenterface ICalculatorCalculator : IDesktopDeviceDesktopDevice {

    importmport dd.idld.idl ; // bring in// bring in IDesktopDeviceDesktopDeviceHRESULT Clear(void);RESULT Clear(void);HRESULT Add([in] short n); // n sent to objectRESULT Add([in] short n); // n sent to objectHRESULTRESULT GetSum([outetSum([out ] short * short * pnn ); // *; // * pnn sent to callerent to caller

    }

    [uuid(DEFACED2uid(DEFACED2 -0229229 -2552552 -1D11D11 -ABBADABBAD00),BBADABBAD00),helpstring(elpstring( Myy Datatypesatatypes )

    ]libraryibrary CalcTypesalcTypes {

    importlib(mportlib( stdole32.tlbtdole32.tlb ); // required; // requiredinterfacenterface ICalculatorCalculator ; // cause TLB inclusion // cause TLB inclusion

    }

    CalcTypes.idlCalcTypes.idl

    COM IDLCOM IDL

  • 8/10/2019 09 COM Fundamentals1

    40/49

    COM IDLCOM IDL -- C++ MappingC++ Mapping#includeinclude dd.hd.h extern const IIDxtern const IID IID_ICalculatorID_ICalculator ;structtruct__declspec uuid_declspec uuid DEFACED1EFACED1-0229229 -2552552 -1D11D11 -ABBADABBAD00BBADABBAD00)))ICalculatorCalculator : publicpublic IDesktopDeviceDesktopDevice {

    virtual HRESULT STDMETHODCALLTYPE Clear(void) = 0;irtual HRESULT STDMETHODCALLTYPE Clear(void) = 0;virtual HRESULT STDMETHODCALLTYPE Add(short n) = 0;irtual HRESULT STDMETHODCALLTYPE Add(short n) = 0;

    virtual HRESULT STDMETHODCALLTYPEirtual HRESULT STDMETHODCALLTYPE GetSum(shortetSum(short *pnn ) = 0; = 0;};;extern const GUIDxtern const GUID LIBID_CalcTypesIBID_CalcTypes ;

    const IIDonst IID IID_ICalculatorID_ICalculator = {0xDEFACED1, 0x0229, 0x2552, {0xDEFACED1, 0x0229, 0x2552,{ 0x1D, 0x11, 0xAB, 0xBA, 0xDA, 0xBB, 0xAD, 0x00 } }; 0x1D, 0x11, 0xAB, 0xBA, 0xDA, 0xBB, 0xAD, 0x00 } };

    const GUIDonst GUID LIBID_CalcTypesIBID_CalcTypes = {0xDEFACED2, 0x0229, 0x2552, {0xDEFACED2, 0x0229, 0x2552,{ 0x1D, 0x11, 0xAB, 0xBA, 0xDA, 0xBB, 0xAD, 0x00 } }; 0x1D, 0x11, 0xAB, 0xBA, 0xDA, 0xBB, 0xAD, 0x00 } };

    CalcTypes.hCalcTypes.h

    CalcTypes_i.cCalcTypes_i.c

  • 8/10/2019 09 COM Fundamentals1

    41/49

    COM IDLCOM IDL Java/VB MappingJava/VB Mapping

    packageackage CalcTypesalcTypes ; // library name // library name/**@**@com.interface iidom.interface iid =DEFACED1DEFACED1-0229229 -2552552 -1D11D11 -ABBADABBAD00)*/BBADABBAD00)*/

    interfacenterface ICalculatorCalculator extendsxtends IDesktopDeviceDesktopDevice {public void Clear( );ublic void Clear( );public void Add(short n);ublic void Add(short n);public voidublic void GetSum(shortetSum(short []] pnn ); // array of length 1; // array of length 1public staticublic static com.ms.com._Guidom.ms.com._Guid iidid =

    new com.ms.com._Guid(0xDEFACED1, 0x0229, 0x2552,ew com.ms.com._Guid(0xDEFACED1, 0x0229, 0x2552,0x1D, 0x11, 0xAB, 0xBA,x1D, 0x11, 0xAB, 0xBA,0xDA, 0xBB, 0xAD, 0x00);xDA, 0xBB, 0xAD, 0x00);

    }

    CalcTypes.javaCalcTypes.java

    Public Sub Clear( )ublic Sub Clear( )Public Subublic Sub Add(ByValdd(ByVal n As Integer) As Integer)Public Subublic Sub GetSum(ByRefetSum(ByRef pnn As Integer)s Integer)

    CalcTypes.clsCalcTypes.cls

  • 8/10/2019 09 COM Fundamentals1

    42/49

    particular valueparticular valueresres

    Severity (31)Severity (31) Facility (27Facility (27 --16)16) Code (15Code (15 --0)0)

    00 -- > Success> Success11 -- > Failure> Failure

    FACILITY_NULLFACILITY_NULLFACILITY_ITFFACILITY_ITFFACILITY_STORAGEFACILITY_STORAGEFACILITY_DISPATCHFACILITY_DISPATCHFACILITY_WINDOWSFACILITY_WINDOWSFACILITY_RPCFACILITY_RPC

    COM And Error HandlingCOM And Error HandlingCOM (today) doesnCOM (today) doesn t support typed C++ or Javat support typed C++ or Java --style exceptionsstyle exceptions

    All (remotable) methods must return a standard 32All (remotable) methods must return a standard 32 --bit error code called an HRESULTbit error code called an HRESULT

    Mapped to exception in higher Mapped to exception in higher --level languageslevel languagesOverloaded to indicate invocation errors from proxiesOverloaded to indicate invocation errors from proxies

  • 8/10/2019 09 COM Fundamentals1

    43/49

    HRESULTsHRESULTsHRESULT names indicate severity and facilityHRESULT names indicate severity and facility

    ____DISP_E_EXCEPTIONDISP_E_EXCEPTIONSTG_S_CONVERTEDSTG_S_CONVERTED

    FACILITY_NULL codes are implicitFACILITY_NULL codes are implicit__S_OKS_OKS_FALSES_FALSEE_FAILE_FAILE_NOTIMPLE_NOTIMPLE_OUTOFMEMORYE_OUTOFMEMORYE_INVALIDARGE_INVALIDARGE_UNEXPECTEDE_UNEXPECTED

    Can useCan use FormatMessageFormatMessage API to lookup humanAPI to lookup human --readablereadabledescription at runtimedescription at runtime

  • 8/10/2019 09 COM Fundamentals1

    44/49

    smallsmall

    longlong

    hyperhyper

    IDLIDL C++C++ JavaJava

    shortshort

    charchar

    longlong

    __int64 __int64

    bytebyte

    intint

    longlong

    shortshort shortshort

    Visual BasicVisual Basic

    N/AN/A

    LongLong

    N/AN/A

    IntegerInteger

    unsigned smallunsigned small

    unsigned longunsigned long

    unsigned hyperunsigned hyper

    unsigned shortunsigned short

    unsigned charunsigned char

    unsigned longunsigned long

    unsigned __int64unsigned __int64

    bytebyte

    intint

    longlong

    unsigned shortunsigned short shortshort

    ByteByte

    N/AN/A

    N/AN/A

    N/AN/A

    floatfloat

    doubledouble

    floatfloat

    doubledouble

    floatfloat

    doubledouble

    SingleSingle

    DoubleDouble

    charchar

    unsigned charunsigned char

    charchar

    unsigned charunsigned char

    charchar

    bytebyte

    N/AN/A

    ByteByte

    wchar_twchar_t wchar_twchar_t charchar Integer Integer

    ScriptScript

    NoNo

    YesYes

    NoNo

    YesYes

    NoNo

    NoNo

    NoNo

    NoNo

    YesYes

    YesYes

    NoNo

    YesYes

    NoNo

    COM Data TypesCOM Data Types

  • 8/10/2019 09 COM Fundamentals1

    45/49

    bytebyte

    booleanboolean

    VARIANT_BOOLVARIANT_BOOL

    IDLIDL C++C++ JavaJava

    BYTEBYTE

    unsigned charunsigned char

    longlong

    VARIANT_BOOLVARIANT_BOOL

    char char

    intint

    booleanboolean

    unsigned charunsigned char bytebyte

    Visual BasicVisual Basic

    N/AN/A

    LongLong

    BooleanBoolean

    ByteByte

    BSTR BSTR

    VARIANTVARIANT

    BSTR BSTR java.lang.String java.lang.String

    VARIANTVARIANT com.ms.com.Variantcom.ms.com.Variant

    StringString

    VariantVariant

    CYCY longlong intint CurrencyCurrency

    DATEDATE

    enumenum

    doubledouble doubledouble

    enumenum intint

    DateDate

    EnumEnum

    TypedTyped ObjRef ObjRef IFooIFoo ** interfaceinterface IFooIFoo IFooIFoo

    structstruct structstruct final classfinal class TypeType

    unionunion

    CC-- style Arraystyle Array

    unionunion N/AN/A

    arrayarray arrayarray

    N/AN/A

    N/AN/A

    ScriptScript

    NoNo

    NoNo

    YesYes

    YesYes

    YesYes

    YesYes

    YesYes

    YesYes

    YesYes

    YesYes

    NoNo

    NoNo

    NoNo

    COM Data TypesCOM Data Types

  • 8/10/2019 09 COM Fundamentals1

    46/49

    struct MESSAGE { VARIANT_BOOL b; long n; };truct MESSAGE { VARIANT_BOOL b; long n; };[ uuid(03C20B33 uuid(03C20B33 -C942942 -11d11d1 -926D26D -006008026FEA), object ]06008026FEA), object ]interfacenterface IAnsweringMachineAnsweringMachine : IUnknown { IUnknown {

    HRESULTRESULT TakeAMessage([inakeAMessage([in ] struct MESSAGE * struct MESSAGE * pmsgmsg );;[propput] HRESULTpropput] HRESULT OutboundMessage([inutboundMessage([in ] longlong msgsg );;[propget] HRESULTpropget] HRESULT OutboundMessage([oututboundMessage([out , retvaletval ] long *p); long *p);

    }

    public final class MESSAGE {ublic final class MESSAGE {public boolean b; public int n;ublic boolean b; public int n;

    }public interfaceublic interface IAnsweringMachineAnsweringMachine extends IUnknownxtends IUnknown{

    public voidublic void TakeAMessage(MESSAGEakeAMessage(MESSAGE msgsg );;public voidublic void putOutboundMessage(intutOutboundMessage(int );;publicublic intnt getOutboundMessageetOutboundMessage (););

    }

    ExampleExample

  • 8/10/2019 09 COM Fundamentals1

    47/49

    f

  • 8/10/2019 09 COM Fundamentals1

    48/49

    ReferencesReferences

    Programming Dist Apps With Visual BasicProgramming Dist Apps With Visual Basicand COMand COM

    Ted Pattison, Microsoft PressTed Pattison, Microsoft PressInside COMInside COM

    DaleDale RogersonRogerson , Microsoft Press, Microsoft Press

    Essential COM(+), 2nd Edition (the book)Essential COM(+), 2nd Edition (the book)Don Box, Addison Wesley Longman (4Q99)Don Box, Addison Wesley Longman (4Q99)

    Essential COM(+) Short Course,Essential COM(+) Short Course,

    DevelopMentor DevelopMentor http://www.develop.comhttp://www.develop.com

    DCOM Mailing ListDCOM Mailing List

    http://http:// discuss.microsoft.comdiscuss.microsoft.com

  • 8/10/2019 09 COM Fundamentals1

    49/49