1 / 28

the first step to COM

the first step to COM. By Huang Yi-Chin 1998/7/28. Outline. 程式語言的危機 What’s COM? 以 C++ 實作 COM Interface COM Object Demo. 程式語言的危機(1/7). 牽一髮動全身 class FastString { char *m_psz; public: FastString(const char *psz); ~FastString(void); void Delete(void); // deletes this instance

jake
Télécharger la présentation

the first step to COM

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. the first step toCOM By Huang Yi-Chin 1998/7/28

  2. Outline • 程式語言的危機 • What’s COM? • 以C++實作COMInterface • COM Object • Demo

  3. 程式語言的危機(1/7) • 牽一髮動全身 class FastString { char *m_psz; public: FastString(const char *psz); ~FastString(void); void Delete(void); // deletes this instance int Length(void) const; int Find(const char *psz) const; // returns offest };

  4. ApplicationA ApplicationB ApplicationC FastString.obj FastString.obj FastString.obj 程式語言的危機(2/7) • Client各有一份FastString.obj

  5. 程式語言的危機(3/7) • 動態連結 class __declspec(dllexport) FastString { char *m_psz; public: FastString(const char *psz); ~FastString(void); void Delete(void); // deletes this instance int Length(void) const; int Find(const char *psz) const; // returns offest };

  6. ApplicationA ApplicationB ApplicationC 程式語言的危機(4/7) FastString Import Library FastString.dll

  7. 程式語言的危機(5/7) • 版本更新時的問題 // FastString ver 2.0 class __declspec(dllexport) FastString { const int m_cch; // count of character char *m_psz; public: FastString(const char *psz); ~FastString(void); void Delete(void); // deletes this instance int Length(void) const; int Find(const char *psz) const; // returns offest };

  8. ApplicationA Ver 2.0 ApplicationB Ver1.0 程式語言的危機(6/7) Sizeof(FastString)==8 Sizeof(FastString)==8 Sizeof(FastString)==4 FastString.dll Ver 2.0 Sizeof(FastString)==4 ApplicationC Ver1.0

  9. 程式語言的危機(7/7) • 各程式語言之間連結困難 • 無法使用舊有的函式庫 • So, we need... • 一套建構在binary code的基礎上,能使各種語言能互相溝通的機制。 • COM : MicroSoft • CORBA : OMG

  10. What’s COM? • COM的簡史 • DDE (Dynamic Data Exchange) • OLE (Object Linking and Embedding) • COM是一種規格 • 規定了製作具有動態替換元件的方法 • Client端程式能與軟體元件相互溝通

  11. 軟體元件的概念 Monolithic Application Component Application A B C new C D E

  12. COM元件的基本要求 • 元件必須以動態連結方式與Client連結 • 元件必須封裝(隱藏)實作上的細節 • 語言獨立性 • 元件必須以Binary Code存在 • 元件升級後必須仍與新舊版本的Client程式相容 • 元件必須具有網路透通性

  13. COM Object、Interface與Client SCV(Object) I_Gather DB.LittleStar (Client) I_BuildStructure Marine(Object) I_Patrol I_Attack

  14. 以C++實作COM介面(1/3) • Virtual Function • declare: virtual MyFun() =0; • Interface / declaration class // interface.h class IFastString { public : virtual int Length(void) const=0; virtual int Find(const char *psz) const=0; };

  15. 以C++實作COM介面(2/3) • Object / implementation class // object.h #include "interface.h" class FastString : public IFastString { const int m_cch; // count of characters char *m_psz; public: FastString(const char *psz); ~FastString(void); int Length(void) const; int Find(const char *psz) const; // returns offest }; Ex:Demo1

  16. FastString &Length Length vptr m_cch &Find Find m_psz 以C++實作COM介面(3/3) • Why Virtual Function works? IFastString &Length vptr &Find

  17. 多重介面與繼承(1/2) • 當物件想要擴充介面的功能時,必須實作另一組介面:(Ex:Demo2) // interface.h ///// class IExtensibleObject { public : virtual void *Dynamic_Cast(const char *pszType)=0; virtual void Delete(void)=0; }; class IPersistentObject : public IExtensibleObject { public : virtual bool Load(const char *pszFileName)=0; virtual bool Save(const char *pszFileName)=0;}; class IFastString : public IExtensibleObject { public : virtual int Length(void) const=0; virtual char* GetString(void) const=0; virtual int Find(const char *psz) const=0;};

  18. 多重介面與繼承(2/2) • 採用多重繼承的方式來使用新的介面 #include "interface.h" class FastString : public IFastString ,public IPersistentObject { const int m_cch; // count of characters char *m_psz; public: FastString(const char *psz); ~FastString(void); // IExtensibleObject methods void *Dynamic_Cast(const char *pszType); void Delete(void); // deletes this instance // IFastString methods int Length(void) const; char* GetString(void) const; int Find(const char *psz) const; // returns offest // IPersistentObject methods bool Load(const char *pszFileName); bool Save(const char *pszFileName);};

  19. 參用計數問題(1/2) • Client不易管理COM Object釋放的時機 void terrenCommander() { IResearch *pIres; IProduce *pIpro; pIres = CreateFactory(“Terren Factory”); if (pIres) { pIres->ResearchSiegeTech(); } pIpro=Dynamic_Cast(“IProduce”); pIpro->produce(“Tank”); pIpro->Delete(); };

  20. 參用計數問題(2/2) • 由COM Object自行記錄參用計數 class IExtensibleObject { public : virtual void *Dynamic_Cast(const char *pszType)=0; //virtual void Delete(void)=0; virtual void DuplicatePointer(void)=0; virtual void DestroyPointer(void)=0; }; • Ex:Demo3

  21. IUnknown(1/2) • 所有介面都必須繼承IUnknown class IExtensibleObject { public : virtual void *Dynamic_Cast(const char *pszType)=0; virtual void DuplicatePointer(void)=0; virtual void DestroyPointer(void)=0; }; interface IUnknown { virtual STDMETHODIMP QueryInterface(REFIID riid, void **ppv)= 0; virtual STDMETHODIMP_(ULONG) AddRef(void) =0; virtual STDMETHODIMP_(ULONG) Release(void)=0; }; • QueryInterface • 利用GUID來query介面

  22. IUnknown(2/2) • IUnknown的構造 FastString IFastString &QueryInterface QueryInterface vptr &AddRef AddRef &Release Release &Find Find ….. …..

  23. 如何識別介面 • GUID (Globally Unique identifier) typedef struct _IID { unsigned long x; unsigned short s1; unsigned short s2; unsigned char c[8]; } IID; extern "C" const IID IID_IPersistentObject = { 0x8ca351c0, 0x24c0, 0x11d2, { 0x8d, 0xa1, 0x0, 0xa0, 0xc9, 0x5c, 0x43, 0x27}}; // {8CA351C0-24C0-11d2-8DA1-00A0C95C4327} • 可利用guidgen.exe產生GUID

  24. HRESULT • HRESULT --32 bit的錯誤識別碼(defined in WINERROR.H) • 常見的HRESULT值 • S_OK • S_FALSE • E_NOINTERFACE • 利用巨集SUCCEEDED來判斷QueryInterface是否有取得interface的指標

  25. COM物件 • 以CLSID作為識別碼 • Registry的概念 • Regedit.exe • \HKEY_CLASSES_ROOT\CLSID\ • ProgID命名慣例 • <應用程式名稱>.<元件名稱>.<版本> • ex.Office.Word.95

  26. 如何建立COM物件 • 使用CoCreateInstance IX* pIX = Null HRESULT hr = ::CoCreateInstance(CLSID_Component, NULL, CLSCTX_ALL, IID_IX, (void**) &pIX); if (SUCCEEDED(hr)) { pIX->Fx(); pIX->Release(); } • 必須在DLL裡實作DllGetObject()函式,取得IClassFactory指標,再利用IClassFactory->CreateInstance()來建立Object

  27. Class Factory COM Library Class Factory Component Client DLL CoCreateInstance CoGetClassObject DllGetClassObject new ClsFactory new FastString time IClsFactory->CreateInstance (IID_IFastString) IClsFactory->Release() pIfs->Length()

  28. 實作上的細節 • 實作元件的DLL檔必須export下列method: • DllRegisterServer • DllUnregisterServer • DllGetObject • DllCanUnloadNow • 利用regsvr32.exe來登錄registry • Demo4: All in one...

More Related