青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

最近看公司的一些新產品和框架 , 發現清一色的“COM思想架構 ”, 這里說的“COM思想架構”是指不完全是標準COM組件的方式,而是指在設計上用到了COM思想。
COM組件技術大概在1993年產生, 20年了, 為什么還有這么多人使用? 
我們先來看看標準COM組件:
標準COM組件(DLL方式)需要實現如下4個導出函數:
DllRegisterServer 將組件信息寫入注冊表
DllUnregisterServer 取消注冊
DllCanUnloadNow判斷組件是否可以從內存中卸載
DllGetClassObject返回IClassFactory指針,然后我們就可以通過該接口的CreateInstance方法創建對象并取得所需的接口。
采用標準COM組件,有很多好處:
面向接口和對象編程
語言無關性, 采用二進制標準,可以實現跨語言調用
版本升級方便,增加新接口, 組件升級后老客戶程序不用重新編譯
位置透明, 客戶程序不用關心組件的位置
重用方便, 通過包容和聚合可以快速重用已有組件
我們可以看到標準COM組件非常強大, 但是很多時候我們并不需要標準COM組件的所有特性,比如我們不希望引入注冊表, 也不希望引入COM運行庫,我們希望我們的程序是完全“綠色”的。這時我們就會采用“COM思想架構“開發非標準的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接口是個偉大的創造!
 IUnknow的AddRef和Release實現對象的引用計數管理, 引用計數用來管理對象的生存周期。
通過引用計數一來可以很方便的共享對象, 另外也能確保對象被正確釋放(確保對象的new和delete在同一模塊中)。
QueryInterface實現接口查詢, 通過這種方式可以很方便的對現有組件進行升級, 只要接口不改 ,可以隨意修改內部實現而不用客戶程序重新編譯。
另外也可以直接增加新接口, 只要在QueryInterface內增加并可以查詢到該新接口, 我們就可以調用該新接口。
我們可以看到QueryInterface讓C++這種靜態語言有了某些動態語言的特性, 在C# 中我們可以通過反射查詢到某個類的成員函數和成員變量, Objective-C中我們也可以根據函數名動態調用某個函數, 在腳本語言中,我們可以在運行時動態查詢和修改某個類的信息。通過COM的QueryInterface, 我們可以動態查詢某個組件類實現哪些接口(函數)。當然他們之間有本質的區別, 動態語言運行時內存中保存有類信息, 而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動態調用某個函數。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的思想卻一直在后續的軟件開發中被使用和發揚, 可以說COM技術是微軟技術框架的“根”(之一)。
posted on 2013-07-20 16:59 Richard Wei 閱讀(4708) 評論(6)  編輯 收藏 引用 所屬分類: COM

FeedBack:
# re: COM思想的背后
2013-07-20 17:16 | WXX
個人以為COM是從技術框架層面實踐了一些設計模式,而設計模式是相對穩定的東西,所以COM背后的思想也相對穩定。COM思想中也有很多不好的東西或者說不好理解的東西,比如:套件、Marshaling等完全可以用其它技術或者框架去替代。至于自動化、類型庫這些,可能微軟自己都不在推崇了,包括基于ATL框架的AX制作慢慢封死了。
COM是思想體現在ABI,以及對象模型的組織上,他自身提供了一些優秀的實踐。  回復  更多評論
  
# re: COM思想的背后
2013-07-20 17:52 | Richard Wei
@WXX
同意, 關于套間、列集/散集, 內部涉及到LPC/RPC技術,微軟隱藏了太多東西,盡管Windows操作系統本身用了不少這方面的技術, 但是外部開發人員卻因為不好掌控而盡量不用。  回復  更多評論
  
# re: COM思想的背后
2013-07-22 09:25 | 永遇樂
微軟通過修改VC編譯器(提供新的關鍵字),讓C++的對象之間擁了有一定的通信能力,這里面關鍵的就是這個iid,通過iid可以在運行時獲取某個對象的成員函數指針,然后調用之,這就相當于對象與對象之間通信了。
這也達到了Object C中對象之間通信的效果(一個對象A給另一個對象B發消息M,B收到消息M后,能處理就處理,不能處理就算了)。
而在COM中,A對象要先看B對象能不能處理消息M,即A先查一下,B對象有沒有處理M消息的那個成員函數HandleM() (即B對象中有沒有哪個接口中有HandleM()方法),如果有(查到了),則調用HandleM(M)。沒查到嘛,當然就算了。  回復  更多評論
  
# re: COM思想的背后
2013-07-23 16:58 | tb
嗯 是的 有很多還是比較實用的  回復  更多評論
  
# re: COM思想的背后
2013-07-27 00:35 | rain
這玩意最主要的一點是 太復雜了 套間 Marshaling這些概念把整個 com 原來一個很優秀簡單的架構搞得很復雜,讓人理解起來很晦澀!  回復  更多評論
  
# re: COM思想的背后
2013-10-24 03:52 | Archie
使用boost的shared_ptr以及C++的RTTI (dynamic_cast)可以輕易實現類似COM IUnknown的框架,并且更簡單  回復  更多評論
  

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品高潮久久| 午夜在线不卡| 亚洲私人影院| 欧美高潮视频| 久久影音先锋| 国产日韩精品一区二区浪潮av| 亚洲破处大片| 欧美肥婆在线| 欧美aa国产视频| 在线日韩中文| 美日韩免费视频| 久久久夜色精品亚洲| 国产嫩草一区二区三区在线观看| 中文国产成人精品| 亚洲国产国产亚洲一二三| 午夜精品久久久久久久久久久久久 | 亚洲视频国产视频| 欧美手机在线| 亚洲一区二区三区在线观看视频| 亚洲精品免费在线播放| 欧美连裤袜在线视频| 一区二区三区欧美亚洲| 一区二区三区四区在线| 国产精品社区| 久久久水蜜桃| 欧美xxx成人| 亚洲图中文字幕| 午夜精彩国产免费不卡不顿大片| 国产欧美一区二区精品秋霞影院 | 久久精品99久久香蕉国产色戒| 午夜在线一区二区| 伊人伊人伊人久久| 亚洲国产日韩欧美一区二区三区| 欧美精品1区| 香蕉久久一区二区不卡无毒影院| 亚洲欧美日韩中文播放| 激情文学综合丁香| 亚洲激情影视| 国产欧美一区二区三区另类精品 | 欧美电影在线| 欧美视频在线观看一区| 欧美在线播放高清精品| 久久美女艺术照精彩视频福利播放| 在线欧美三区| 一区二区三区视频观看| 国内视频一区| 亚洲美女诱惑| 一区二区三区在线高清| 亚洲精品婷婷| 一区二区三区在线观看欧美 | 亚洲第一黄色网| 亚洲电影成人| 国产欧美一级| 欧美大片免费观看| 国产精品一区二区三区四区 | 欧美深夜影院| 美日韩精品免费| 欧美色图首页| 久热综合在线亚洲精品| 欧美日韩另类丝袜其他| 鲁大师影院一区二区三区| 欧美女同视频| 久久一区国产| 国产精品日韩欧美一区| 欧美激情第9页| 国色天香一区二区| 亚洲图片欧美日产| 99re6这里只有精品| 久久精品午夜| 亚洲欧美日韩直播| 欧美精品久久一区| 免费久久99精品国产| 国产乱码精品一区二区三区五月婷 | 欧美激情va永久在线播放| 国产精品乱码久久久久久| 亚洲夫妻自拍| 国内精品久久久久久久影视蜜臀 | 国产香蕉久久精品综合网| 亚洲区一区二区三区| 在线精品国精品国产尤物884a| 亚洲一二三区在线| 亚洲网在线观看| 欧美日韩精品一区二区天天拍小说| 久久夜色精品亚洲噜噜国产mv | 亚洲综合久久久久| 欧美日韩精品免费在线观看视频| 亚洲成人在线视频网站| 在线看不卡av| 麻豆9191精品国产| 欧美激情1区2区| 亚洲区中文字幕| 欧美激情精品久久久久久黑人| 欧美福利一区二区| 亚洲精品视频啊美女在线直播| 免费不卡亚洲欧美| 欧美国产1区2区| 亚洲国产成人久久| 美女精品在线观看| 亚洲国产另类 国产精品国产免费| 亚洲国产老妈| 欧美激情一区二区| 亚洲免费播放| 亚洲欧美视频在线观看| 国产欧美一区二区三区在线看蜜臀 | 美女啪啪无遮挡免费久久网站| 国产日韩亚洲| 性色av一区二区三区红粉影视| 性色av一区二区三区| 国产手机视频一区二区| 久久精品99久久香蕉国产色戒| 久久免费精品日本久久中文字幕| 一区精品在线| 欧美激情一区二区三区成人| 99精品热视频只有精品10| 午夜精品www| 一区二区三区在线视频观看| 欧美大片免费久久精品三p| 日韩天堂av| 久久精品国产99| 亚洲国产91色在线| 欧美视频精品一区| 久久精品国产亚洲aⅴ| 亚洲国产精品毛片| 午夜视频一区在线观看| 黑人巨大精品欧美黑白配亚洲| 另类图片综合电影| 亚洲精品一区二区三区在线观看| 一区二区三区回区在观看免费视频| 国产精品久久久久久久午夜片| 久久精品国产欧美亚洲人人爽| 亚洲激情网站免费观看| 久久国产精品免费一区| 亚洲精品久久久蜜桃| 国产精品久久久久久久久久久久 | 亚洲女同同性videoxma| 免费日韩成人| 亚洲综合色在线| 亚洲电影免费在线观看| 国产精品入口66mio| 麻豆成人精品| 午夜国产不卡在线观看视频| 亚洲国产一区二区视频| 久久都是精品| 亚洲尤物在线| 日韩天堂在线观看| 精品91在线| 国产精品一区二区三区观看 | 午夜精品电影| 日韩视频一区二区三区| 国内精品模特av私拍在线观看| 欧美日韩精品在线观看| 久热国产精品| 久久国产福利国产秒拍| 亚洲一区在线播放| 亚洲精品亚洲人成人网| 欧美成人一区在线| 久久精品视频播放| 亚洲欧美日韩成人高清在线一区| 亚洲人午夜精品| 亚洲高清视频在线| 一区二区三区自拍| 国产在线观看一区| 国产精品视频最多的网站| 欧美日韩裸体免费视频| 欧美激情视频给我| 欧美高清视频一区二区| 美女图片一区二区| 久久中文在线| 久久天天躁狠狠躁夜夜爽蜜月| 欧美一区激情视频在线观看| 亚洲欧美在线磁力| 影音先锋一区| 欧美日韩亚洲不卡| 牛牛国产精品| 蜜臀av性久久久久蜜臀aⅴ四虎| 欧美亚洲综合在线| 亚洲欧美中文另类| 午夜欧美不卡精品aaaaa| 中文亚洲欧美| 亚洲自拍偷拍网址| 性欧美video另类hd性玩具| 亚洲综合99| 欧美一级久久久久久久大片| 午夜伦欧美伦电影理论片| 亚洲欧美在线一区二区| 久久成人18免费网站| 久久久精品一区二区三区| 久久久夜夜夜| 欧美刺激午夜性久久久久久久| 欧美77777| 欧美日韩亚洲一区二区| 国产精品爽黄69| 国内精品久久久| 最新日韩中文字幕| 亚洲一区二区三区四区五区午夜| 亚洲一区999| 久久亚洲一区二区| 最新69国产成人精品视频免费| 一本色道久久综合一区| 午夜欧美大尺度福利影院在线看|