1 / 63

Implementing COM Objects

Implementing COM Objects. 主講人:虞台文. Content. Types of COM Servers Objects with Single interface Example  Enumerators Objects with Multiple interfaces Example  Personal Account Server Modules of COM Class Factory & IClassFactory Example  Simple Object Self-Registration

Download Presentation

Implementing COM Objects

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. Implementing COM Objects 主講人:虞台文

  2. Content • Types of COM Servers • Objects with Single interface • Example  Enumerators • Objects with Multiple interfaces • Example  Personal Account • Server Modules of COM • Class Factory & IClassFactory • Example  Simple Object • Self-Registration • InProcess Severs by MFC

  3. OLEObject Linking & Embedding Types of COM Servers

  4. Call interface members Server Object  Get object interface pointer, and return to Client   Create object of a CLSID Locate implementation, and load or launch server CoCreateInstance() Using COM Object Client COM Library

  5. Call interface members Server Object  Get object interface pointer, and return to Client   Create object of a CLSID Locate implementation, and load or launch server CoCreateInstance() Where is the server located? Client COM Library

  6. Local server process Client Process In-process server In-process object COM Local server Stub Local object RPC COM Remote Machine Local object proxy Remote server process COM Remote server Stub Remote object Remote object proxy RPC Server Types Client

  7. OLEObject Linking & Embedding Objects with Single Interface

  8. Template of Enumerators template <class ELT_T> interface IEnum : IUnknown{virtual HRESULT Next(ULONG celt, ELT_T *rgelt, ULONG *pceltFetched)=0;virtual HRESULT Skip(ULONG celt)=0;virtual HRESULT Reset(void)=0;virtual HRESULT Clone(IEnum<ELT_T> ** ppEnum)=0;};

  9. IEnumXxx

  10. Example: Enumerate Rectangles

  11. Example: Enumerate Rectangles

  12. Example: Enumerate Rectangles

  13. IEnumRECT // IEmnuRect.h #if !defined(IEnumRECT_HEARDER) #define IEnumRECT_HEARDER #include <objbase.h> #undef INTERFACE #define INTERFACE IEnumRECT DECLARE_INTERFACE_(IEnumRECT, IUnknown) { // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IEnumRECT methods STDMETHOD(Next)(THIS_ DWORD, LPRECT, LPDWORD) PURE; STDMETHOD(Skip)(THIS_ DWORD) PURE; STDMETHOD(Reset)(THIS) PURE; STDMETHOD(Clone)(THIS_ IEnumRECT **) PURE; }; // {6E699FBF-5ED3-44f2-A547-1481C54E130A} DEFINE_GUID(IID_IEnumRECT, 0x6e699fbf, 0x5ed3, 0x44f2, 0xa5, 0x47, 0x14, 0x81, 0xc5, 0x4e, 0x13, 0xa); typedef IEnumRECT * LPENUMRECT; #endif// !defined(IEnumRECT_HEARDER)

  14. CEnumRect // EnumRect.cpp //..................................... #include <afxtempl.h> #include "IEnumRect.h" class CEnumRect : public IEnumRECT { private: DWORD m_cRef; //Reference count DWORD m_iCur; //Current enum position CArray<RECT, RECT> m_rects; //RECTS we enumerate public: CEnumRect(CArray<RECT, RECT>& rects); virtual ~CEnumRect(); //IUnknown members STDMETHODIMP QueryInterface(REFIID, void **); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); //IEnumRECT members STDMETHODIMP Next(ULONG, LPRECT, ULONG *); STDMETHODIMP Skip(ULONG); STDMETHODIMP Reset(void); STDMETHODIMP Clone(LPENUMRECT *); }; //.....................................

  15. Constructor/Destructor CEnumRect::CEnumRect(CArray<RECT, RECT>& rects) { m_rects.Copy(rects); //Ref counts always start at zero m_cRef=0; //Current pointer is the first element m_iCur=0; } CEnumRect::~CEnumRect(void) { }

  16. CEnumRect::QueryInterface STDMETHODIMP CEnumRect::QueryInterface(REFIID riid, void** ppv) { //Always NULL the out-parameters *ppv=NULL; // No explicit typecast necessary since we singly derive // from IEnumRECT. if (IID_IUnknown==riid || IID_IEnumRECT==riid) *ppv= this; // == (LPUNKNOWN) this; if (NULL==*ppv) return ResultFromScode(E_NOINTERFACE); //AddRef any interface we'll return. ((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; }

  17. CEnumRect::AddRef, Release STDMETHODIMP CEnumRect::AddRef(void) { return ++m_cRef; } STDMETHODIMP_(ULONG) CEnumRect::Release(void) { if (0 != --m_cRef) return m_cRef; delete this; return 0; }

  18. Exercise • Implementing objects with interfaces IEnumSentence and and IEnumWord for enumerating the sentences and words from a text file.

  19. OLEObject Linking & Embedding Objects with Multiple Interfaces

  20. Three Methods • Interface Implementations • Contained Interface Classes • Multiple Inheritance

  21. IUnknown Personal Account IBanking IPettyCash Example: Personal Account

  22. IBanking and IPettyCash // Account.h #if !defined(IBanking_IPettyCash_HEARDER) #define IBanking_IPettyCash_HEARDER #include <objbase.h> #undef INTERFACE #define INTERFACE IBanking DECLARE_INTERFACE_(IBanking, IUnknown) { // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IBanking methods STDMETHOD(Deposit)(THIS_ UINT) PURE; STDMETHOD(Withdraw)(THIS_ UINT) PURE; STDMETHOD(Balance)(THIS_ UINT *) PURE; }; // {8B5D2FC3-5633-423e-B846-4315F10F7C4A} DEFINE_GUID(IID_IBanking, 0x8b5d2fc3, 0x5633, 0x423e, 0xb8, 0x46, 0x43, 0x15, 0xf1, 0xf, 0x7c, 0x4a); typedef IBanking * LPBANKING;

  23. IBanking and IPettyCash // Account.h #if !defined(IBanking_IPettyCash_HEARDER) #define IBanking_IPettyCash_HEARDER #include <objbase.h> #undef INTERFACE #define INTERFACE IBanking DECLARE_INTERFACE_(IBanking, IUnknown) { // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IBanking methods STDMETHOD(Deposit)(THIS_ UINT) PURE; STDMETHOD(Withdraw)(THIS_ UINT) PURE; STDMETHOD(Balance)(THIS_ UINT *) PURE; }; // {8B5D2FC3-5633-423e-B846-4315F10F7C4A} DEFINE_GUID(IID_IBanking, 0x8b5d2fc3, 0x5633, 0x423e, 0xb8, 0x46, 0x43, 0x15, 0xf1, 0xf, 0x7c, 0x4a); typedef IBanking * LPBANKING; #undef INTERFACE #define INTERFACE IPettyCash DECLARE_INTERFACE_(IPettyCash, IUnknown) { // IUnknown methods STDMETHOD(QueryInterface)(THIS_ REFIID, void **) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; // IPettyCash methods STDMETHOD(Income)(THIS_ UINT) PURE; STDMETHOD(Pay)(THIS_ UINT) PURE; STDMETHOD(Cash)(THIS_ UINT *) PURE; }; // {7DCD4D1B-085E-40a7-93FE-4123E6F4C726} DEFINE_GUID(IID_IPettyCash, 0x7dcd4d1b, 0x85e, 0x40a7, 0x93, 0xfe, 0x41, 0x23, 0xe6, 0xf4, 0xc7, 0x26); typedef IPettyCash * LPPETTYCASH; #endif// !defined(IBanking_IPettyCash_HEARDER)

  24. Three Methods • Interface Implementations • Contained Interface Classes • Multiple Inheritance

  25. Exercise • Define interfaces for an object which manages personal data used in usual life, e.g., personal information and address book. You also need an interface (e.g., IPersistFile) to access the information from a file. • Implement the personal-data object including the interfaces you defined using the three methods described in this lecture. • Write an MFC application using the personal-data object.

  26. OLEObject Linking & Embedding Server Modules of COM

  27. Implementation can be independent of execution context. Object Class factory: Creates objects Implementation differs between DLL and EXE servers. The Generic Structure of a Server Module Object interfaces (as many as desired) IClassFactory(2) Registration Exposure for Class factory Unloading mechanism Sever module

  28. Registry Entries In-process servers: InprocServer32=<path to DLL> Object handlers: InprocHandler32=<path to DLL> Local servers: LocalServer32=<path to EXE>

  29. Self-Registration • DLL Servers • DllRegisterServer • DllUnregisterServer • EXE servers  Command arguments • /RegServer • /UnregServer

  30. Server Emulation \ CLSID {42754580-16b7-11ce-80eb-00aa003d7352} = Original ComponentTreatAs = {6fa820f0-2e48-11ce-80eb-00aa003d7352}AutoTreatAs = {6fa820f0-2e48-11ce-80eb-00aa003d7352}InprocServer32 = c:\older\original.dll {6fa820f0-2e48-11ce-80eb-00aa003d7352} = New Emulating ComponentInprocServer32 = c:\newer\emulator.dll

  31. Some API’s • CoGetClassObject • CoCreateInstance(Ex) • CoGetTreatAsClass • CoTreatAsClass

  32. Exercises • Read the APIs for server emulations. • Lookup system registry to find some entries with TreatAs and AutoTreatAs keys.

  33. OLEObject Linking & Embedding Class Factory & IClassFactory

  34. Server Class factory (an object) Client Object The Class-Factory Object  IClassFactory- ::CreateInstance  Factory manufactures object.  Factory returns New interface Pointer to client

  35. IClassFactory interface IClassFactory : IUnknown{ HRESULT CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv); HRESULT LockServer(BOOL fLock);};

  36. Licensing with IClassFactory2 interface IClassFactory2 : IClassFactory{ HRESULT GetLicInfo(LPLICINFO pLicInfo); HRESULT RequestLicKey(DWORD dwResrved, BSTR FAR* pbstrKey); HRESULT CreateInstanceLic(IUnknown *pUnkOuter, IUnknown *pUnkReserved, REFIID riid, BSTR bstrKey, void **ppvObject);};

  37. Exposing the Class Factory In-Process Server • Implement DllGetClassObject • Implement DllCanUnloadNow STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv); STDAPI DllCanUnloadNow(void);

  38. Exposing the Class Factory Local Server • CoRegisterClassObject • CoRevokeClassObject STDAPI CoRegisterClassObject( REFCLSID rclsid, IUnknown * pUnk, DWORD dwClsContext, DWORD flags, LPDWORD lpdwRegister ); HRESULT CoRevokeClassObject(DWORDdwRegister);

  39.          In-Process-Server Creation

  40.         Local-Server Creation

  41. Create Multiple COM Objects Step1. Get IClassFactory by Step2. Call IClassFactory::CreateInstance(…)a number of time if multiple objects are needed Step3. Call IClassFactory::Release(). STDAPI CoGetClassObject( REFCLSID rclsid, //CLSID associated with the class object DWORD dwClsContext, //Context for running executable code COSERVERINFO * pServerInfo, //Pointer to machine on which the object is to // be instantiated REFIID riid, //Reference to the identifier of the interface LPVOID * ppv //Address of output variable that receives the // interface pointer requested in riid );

  42. Create Single COM Objects STDAPI CoCreateInstance( REFCLSID rclsid, //Class identifier (CLSID) of the object LPUNKNOWN pUnkOuter, //Pointer to controlling IUnknown DWORD dwClsContext, //Context for running executable code REFIID riid, //Reference to the identifier of the interface LPVOID * ppv //Address of output variable that receives // the interface pointer requested in riid );

  43. CoGetClassObject() vs. CoCreateInstance() STDAPI CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwContext, REFIID iid, void **ppv){ HRESULT hr; IClassFactory *pCF; *ppv=NULL; hr=CoGetClassObject(rclsid, dwContext, NULL, IID_IClassFactory, (void **) &pCF);if (FAILED(hr)) return hr; hr=pCF->CreateInstance(pUnkOuter, iid, ppv); pCF->Release(); return hr;}

  44. OLEObject Linking & Embedding Example  Simple Object

  45. Example: Simple Object  In-Process Sever

  46. Exercises • The above example create COM object using CoCreateInstance(). Modify it by using class factory. • Modify the server of the above example so that it can create multiple classes of COM object. • Code the problem in Exercise 3 as an in-process server, and write an MFC application to use the object.

  47. OLEObject Linking & Embedding Self-Registration

  48. Some Registry Functions • RegCreateKey(Ex) • RegSetValue(Ex) • RegCloseKey • RegOpenKey(Ex) • RegEnumKey(Ex) • RegEnumValue • RegQueryInfoKey • RegDeleteKey

  49. RegSvr32.EXE

  50. DEF File ;DSimpleObject.def : 聲明動態庫DLL的模組參數. LIBRARY DSimpleObject DESCRIPTION '我的第一個純 C++ COM 對象' EXPORTS DllRegisterServer PRIVATE ; COM server registration DllUnregisterServer PRIVATE ; COM server deregistration DllCanUnloadNow PRIVATE DllGetClassObject PRIVATE

More Related