<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      厚積薄發(fā)
      海納百川,有容乃大
      最近看公司的一些新產品和框架 , 發(fā)現清一色的“COM思想架構 ”, 這里說的“COM思想架構”是指不完全是標準COM組件的方式,而是指在設計上用到了COM思想。

      COM組件技術大概在1993年產生, 20年了, 為什么還有這么多人使用? 

      我們先來看看標準COM組件:
      標準COM組件(DLL方式)需要實現如下4個導出函數:
      DllRegisterServer 將組件信息寫入注冊表
      DllUnregisterServer 取消注冊
      DllCanUnloadNow判斷組件是否可以從內存中卸載
      DllGetClassObject返回IClassFactory指針,然后我們就可以通過該接口的CreateInstance方法創(chuàng)建對象并取得所需的接口。

      采用標準COM組件,有很多好處:
      面向接口和對象編程
      語言無關性, 采用二進制標準,可以實現跨語言調用
      版本升級方便,增加新接口, 組件升級后老客戶程序不用重新編譯
      位置透明, 客戶程序不用關心組件的位置
      重用方便, 通過包容和聚合可以快速重用已有組件

      我們可以看到標準COM組件非常強大, 但是很多時候我們并不需要標準COM組件的所有特性,比如我們不希望引入注冊表, 也不希望引入COM運行庫,我們希望我們的程序是完全“綠色”的。這時我們就會采用“COM思想架構“開發(fā)非標準的COM組件。

      實際上微軟本身已經有很多API采用這種設計方案了,我們來看一些例子:

      XmlLite
      繼msxml之后微軟提供的另 一款高效的XML解析器, 它本身只有一個綠色DLL XmlLite.dll, 關于它的接口和使用方法可以參考XmlLite Introduction用于本機 C++ 的小巧快捷的 XML 分析器
      我們可以用depends.exe看看該DLL的導出函數:


      調用這些導出的CreateXXX函數返回返回一個繼承于IUnknown的接口, 然后我們就可以調用接口提供的方法了, 可以看下IXmlReader的方法: 
          IXmlReader : public IUnknown
          {
          
      public:
              
      virtual HRESULT STDMETHODCALLTYPE SetInput( 
                  
      /* [annotation] */ 
                  __in_opt  IUnknown 
      *pInput) = 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE GetProperty( 
                  
      /* [annotation] */ 
                  __in  UINT nProperty,
                  
      /* [annotation] */ 
                  __out  LONG_PTR 
      *ppValue) = 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE SetProperty( 
                  
      /* [annotation] */ 
                  __in  UINT nProperty,
                  
      /* [annotation] */ 
                  __in_opt  LONG_PTR pValue) 
      = 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE Read( 
                  
      /* [annotation] */ 
                  __out_opt  XmlNodeType 
      *pNodeType) = 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE GetNodeType( 
                  
      /* [annotation] */ 
                  __out  XmlNodeType 
      *pNodeType) = 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE MoveToFirstAttribute( void= 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE MoveToNextAttribute( void= 0;
              

              .......

              
          };

      Direct2D
      關于是微軟下一代2D渲染接口, 關于它的詳情參考Direct2D, 我們同樣分析一下它的導出函數:

      實際看到這里也用了COM思想的方法,我們可以看看D2D1CreateFactory返回的ID2D1Factory的接口: 
      interface DX_DECLARE_INTERFACE("06152247-6f50-465a-9245-118bfd3b6007") ID2D1Factory  : public IUnknown
      {
          
      //
          
      // Cause the factory to refresh any system metrics that it might have been snapped
          
      // on factory creation.
          
      //
          STDMETHOD(ReloadSystemMetrics)(
              ) PURE;
          
          
      //
          
      // Retrieves the current desktop DPI. To refresh this, call ReloadSystemMetrics.
          
      //
          STDMETHOD_(void, GetDesktopDpi)(
              _Out_ FLOAT 
      *dpiX,
              _Out_ FLOAT 
      *dpiY 
              ) PURE;
          
          STDMETHOD(CreateRectangleGeometry)(
              _In_ CONST D2D1_RECT_F 
      *rectangle,
              _Outptr_ ID2D1RectangleGeometry 
      **rectangleGeometry 
              ) PURE;
          
          STDMETHOD(CreateRoundedRectangleGeometry)(
              _In_ CONST D2D1_ROUNDED_RECT 
      *roundedRectangle,
              _Outptr_ ID2D1RoundedRectangleGeometry 
      **roundedRectangleGeometry 
              ) PURE;
          
          STDMETHOD(CreateEllipseGeometry)(
              _In_ CONST D2D1_ELLIPSE 
      *ellipse,
              _Outptr_ ID2D1EllipseGeometry 
      **ellipseGeometry 
              ) PURE;
          
          ......

      }; 
      // interface ID2D1Factory

      思考為什么會有越來越多的新程序采用這種”COM思想架構“, 這個要回到COM的根 ---- IUnknown接口:

          IUnknown
          {
          
      public:
              BEGIN_INTERFACE
              
      virtual HRESULT STDMETHODCALLTYPE QueryInterface( 
                  
      /* [in] */ REFIID riid,
                  
      /* [annotation][iid_is][out] */ 
                  __RPC__deref_out  
      void **ppvObject) = 0;
              
              
      virtual ULONG STDMETHODCALLTYPE AddRef( void= 0;
              
              
      virtual ULONG STDMETHODCALLTYPE Release( void= 0;
              
              END_INTERFACE
          };

      IUnknow接口是個偉大的創(chuàng)造!

       IUnknow的AddRef和Release實現對象的引用計數管理, 引用計數用來管理對象的生存周期。
      通過引用計數一來可以很方便的共享對象, 另外也能確保對象被正確釋放(確保對象的new和delete在同一模塊中)。

      QueryInterface實現接口查詢, 通過這種方式可以很方便的對現有組件進行升級, 只要接口不改 ,可以隨意修改內部實現而不用客戶程序重新編譯。
      另外也可以直接增加新接口, 只要在QueryInterface內增加并可以查詢到該新接口, 我們就可以調用該新接口。

      我們可以看到QueryInterface讓C++這種靜態(tài)語言有了某些動態(tài)語言的特性, 在C# 中我們可以通過反射查詢到某個類的成員函數和成員變量, Objective-C中我們也可以根據函數名動態(tài)調用某個函數, 在腳本語言中,我們可以在運行時動態(tài)查詢和修改某個類的信息。通過COM的QueryInterface, 我們可以動態(tài)查詢某個組件類實現哪些接口(函數)。當然他們之間有本質的區(qū)別, 動態(tài)語言運行時內存中保存有類信息, 而C++的QueryInterface通過switch case, 返回的是存有虛表指針的對象指針。

      最后再簡單談下IUnknown的升級版IDispatch和IInspectable。

      先看IDispatch: 
          IDispatch : public IUnknown
          {
          
      public:
              
      virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount( 
                  
      /* [out] */ __RPC__out UINT *pctinfo) = 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE GetTypeInfo( 
                  
      /* [in] */ UINT iTInfo,
                  
      /* [in] */ LCID lcid,
                  
      /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) = 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( 
                  
      /* [in] */ __RPC__in REFIID riid,
                  
      /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
                  
      /* [range][in] */ UINT cNames,
                  
      /* [in] */ LCID lcid,
                  
      /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId) = 0;
              
              
      virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( 
                  
      /* [in] */ DISPID dispIdMember,
                  
      /* [in] */ REFIID riid,
                  
      /* [in] */ LCID lcid,
                  
      /* [in] */ WORD wFlags,
                  
      /* [out][in] */ DISPPARAMS *pDispParams,
                  
      /* [out] */ VARIANT *pVarResult,
                  
      /* [out] */ EXCEPINFO *pExcepInfo,
                  
      /* [out] */ UINT *puArgErr) = 0;
              
          };

      IDispatch繼承于IUnknown, 通過IDispatch, 我們可以實現腳本語言對COM組件的調用,我們可以通過GetTypeInfo獲取對象的類型信息, 通過GetIDsOfNames函數以字符串的方式獲取函數的DISPID, 通過Invoke動態(tài)調用某個函數。IE的DOM對象與JS的交互全部是通過IDispatch(Ex)接口實現的。當然,除非你的組件要與腳本語言交互, 否者一般不用實現該接口。

      再看IInspectable: 
          IInspectable : public IUnknown
          {
          
      public:
              
      virtual HRESULT STDMETHODCALLTYPE GetIids( 
                  
      /* [out] */ __RPC__out ULONG *iidCount,
                  
      /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID **iids) = 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE GetRuntimeClassName( 
                  
      /* [out] */ __RPC__deref_out_opt HSTRING *className) = 0;
              
              
      virtual HRESULT STDMETHODCALLTYPE GetTrustLevel( 
                  
      /* [out] */ __RPC__out TrustLevel *trustLevel) = 0;
              
          };

      IInspectable也繼承于IUnknown, 它是WinRT所有對象的基接口, 所以WinRT還是基于COM技術。
      其中GetTrustLevel返回信任等級, GetRuntimeClassName返回類名, 而GetIids返回當前類對象實現了哪些接口(所有接口的iid), 得到接口的iid后, 我們就可以通過QueryInterface查詢我們需要的接口了, 得到接口指針就可以調用內部函數了。

      最后總結下,回答下文章開頭的問題, 很多人說COM過時了, 也許”純正的標準COM“確實是使用的人越來越少了, 但是COM的思想卻一直在后續(xù)的軟件開發(fā)中被使用和發(fā)揚, 可以說COM技術是微軟技術框架的“根”(之一)。
      posted on 2013-07-20 17:16  Richard Wei  閱讀(2350)  評論(10)    收藏  舉報

      主站蜘蛛池模板: 成全我在线观看免费第二季| 成人免费无遮挡在线播放| 欧美三级不卡在线观线看高清| 国产成人精彩在线视频| 午夜亚洲国产理论片亚洲2020| 国产精品播放一区二区三区| 激情综合网激情国产av| 国产睡熟迷奷系列网站| 日韩有码中文在线观看| 男人狂桶女人出白浆免费视频 | 骚虎视频在线观看| 成年无码av片在线蜜芽| 老熟妇国产一区二区三区| 亚洲男人天堂av在线| 性男女做视频观看网站 | 亚洲区综合中文字幕日日| 国产农村激情免费专区| 亚洲日韩AV秘 无码一区二区| 亚洲无人区一码二码三码| 51午夜精品免费视频| 成人乱码一区二区三区四区| 国产AV大陆精品一区二区三区| 国产欲女高潮正在播放| 高台县| 女同另类激情在线三区| 中文字幕日韩一区二区不卡| 亚洲午夜伦费影视在线观看| 成人午夜大片免费看爽爽爽| 亚洲成av人最新无码不卡短片| 麻豆成人传媒一区二区| 在线国产精品中文字幕| av天堂久久精品影音先锋| 亚洲色欲或者高潮影院 | 亚洲无线看天堂av| 日韩亚洲精品中文字幕| 亚洲男人的天堂av手机在线观看| 亚洲乱妇老熟女爽到高潮的片| 国产熟女真实乱精品51| 亚洲午夜福利网在线观看| 成人亚洲欧美一区二区三区| 亚洲中文字幕久久精品码|