日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

《COM原理与应用》学习笔记二——COM对象和COM接口的实现

發(fā)布時(shí)間:2023/12/9 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《COM原理与应用》学习笔记二——COM对象和COM接口的实现 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  COM對(duì)象是給用戶(hù)提供服務(wù)的封裝的實(shí)體。這個(gè)應(yīng)該和C++中類(lèi)的對(duì)象理解起來(lái)是相似的。但是有時(shí)候也把COM對(duì)象當(dāng)作提供服務(wù)的那個(gè)類(lèi)。COM對(duì)象也對(duì)數(shù)據(jù)進(jìn)行了封裝,然后也提供了接口。不過(guò)和類(lèi)還是有一些不一樣的。類(lèi)中的數(shù)據(jù)可以申明為public,然后讓用戶(hù)能夠直接訪(fǎng)問(wèn)這些數(shù)據(jù)成員。但是用戶(hù)不能對(duì)COM對(duì)象的數(shù)據(jù)進(jìn)行直接訪(fǎng)問(wèn),只能通過(guò)接口(如果有提供這種接口的話(huà))來(lái)對(duì)數(shù)據(jù)進(jìn)行間接的訪(fǎng)問(wèn)。一般COM接口指的是一組提供服務(wù)的接口,剛開(kāi)始看這個(gè)定義很不習(xí)慣。因?yàn)镃++中根本沒(méi)有接口的概念,但是像Java這些語(yǔ)言就有接口的概念。關(guān)于COM接口可以按照J(rèn)ava的接口來(lái)理解(多懂幾門(mén)語(yǔ)言真心是好事啊)。C++中的定義方式一般是用抽象類(lèi)來(lái)實(shí)現(xiàn),其中所有的函數(shù)全都是純需函數(shù),全部交給子類(lèi)來(lái)實(shí)現(xiàn)。如某個(gè)接口的定義如下:

  

1 struct ICalc 2 { 3 virtual long __stdcall add(long a, long b) = 0; 4 virtual long __stdcall minus(long a, long b) = 0; 5 virtual long __stdcall times(long a, long b) = 0; 6 virtual long __stdcall devide(long a, long b) = 0; 7 };

  客戶(hù)使用COM組件的時(shí)候,是不知道COM組件的確切對(duì)象的。所以COM組件需要注冊(cè)注冊(cè)表。但是客戶(hù)還是需要一點(diǎn)什么標(biāo)識(shí)來(lái)訪(fǎng)問(wèn)COM組件,使用COM對(duì)象,第一個(gè)直接的想法就是取個(gè)名字。但是會(huì)出現(xiàn)這種情況,A公司做個(gè)插件叫做Calculator,B公司做個(gè)插件也可以叫做Calculator,甚至家里的旺財(cái)寫(xiě)個(gè)插件都可以叫做Calculator。所以這個(gè)方法不是很好。為了解決這個(gè)重復(fù)的問(wèn)題。微軟決定使用GUID來(lái)對(duì)插件進(jìn)行標(biāo)識(shí)。GUID全稱(chēng)是Globally Unique Identifier,是一個(gè)128位的隨機(jī)數(shù)。大家都隨機(jī),不怕隨到一樣的數(shù)嗎?恩,確實(shí)有那個(gè)可能,但是這個(gè)概率太低了。理論上,如果一臺(tái)計(jì)算機(jī)每秒產(chǎn)生10 000 000個(gè)GUID,則可以保證3240年不重復(fù)(當(dāng)然是概率意義上,怎么算的了,我也不清楚啦)。反正GUID重復(fù)的概率是非常低的,可以放心使用。每個(gè)COM對(duì)象都有一個(gè)GUID來(lái)進(jìn)行標(biāo)識(shí),這個(gè)GUID一般叫做CLSID。每一個(gè)COM接口也有一個(gè)GUID來(lái)進(jìn)行標(biāo)識(shí),這個(gè)GUID一般叫做IID。在C++中,GUID定義如下:

1 typedef struct _GUID 2 { 3 DWORD Data1; 4 WORD Data2; 5 WORD Data3; 6 BYTE Data4[8]; 7 } GUID;

  按照COM規(guī)范,只要用戶(hù)獲得了一個(gè)COM對(duì)象的接口,那么用戶(hù)可以通過(guò)它獲取到該COM對(duì)象的其他接口(如果有的話(huà))。一個(gè)用戶(hù)在使用COM對(duì)象以前,用戶(hù)需要建立COM對(duì)象(我覺(jué)得COM對(duì)象這個(gè)叫法真心的很討厭,書(shū)上說(shuō)COM對(duì)象既指那個(gè)提供服務(wù)的類(lèi),也指根據(jù)這個(gè)類(lèi)實(shí)例化的對(duì)象)。建立COM對(duì)象當(dāng)然是要分配一些資源的,在用完這些資源以后當(dāng)然也是需要釋放的,所以每一個(gè)COM對(duì)象都有一個(gè)計(jì)數(shù)。計(jì)數(shù)值為0的時(shí)候,那么對(duì)象就銷(xiāo)毀這個(gè)COM對(duì)象。當(dāng)有另外一個(gè)指針獲得這個(gè)COM對(duì)象的話(huà),那么計(jì)數(shù)就會(huì)增加一個(gè),有一個(gè)指針釋放了對(duì)這個(gè)COM對(duì)象的控制了,那么計(jì)數(shù)就減一。這種計(jì)數(shù)的方式類(lèi)似于智能指針。但是COM對(duì)象的計(jì)數(shù)也沒(méi)有智能指針那么智能,有時(shí)還是需要手動(dòng)來(lái)釋放的,所以用戶(hù)承擔(dān)著釋放資源的重任。基于以上的說(shuō)法,我們就需要一個(gè)獲取其他所有接口的接口,增加計(jì)數(shù)的接口和減少計(jì)數(shù)的接口。COM提供的IUnknown接口已經(jīng)提供了這三個(gè)接口(注意:COM接口一般指的是一組接口,而不是一個(gè)接口)。實(shí)際上所有的COM接口都必須從IUnknown繼承而來(lái)。IUnknown提供了QueryInterface、AddRef和Release這三個(gè)接口。按C++的定義如下,但是實(shí)際定義的寫(xiě)法比較麻煩,這里只是比較簡(jiǎn)單的寫(xiě)法。

1 class IUnknown 2 { 3 public: 4 virtual HRESULT __stdcall QueryInterface(const IID &iid, void **ppv) =0; 5 virtual ULONG __stdcall AddRef() =0; 6 virtual ULONG __stdcall Release() = 0; 7 }

IUnknown是一個(gè)接口當(dāng)然也有一個(gè)IID,IUnknown的IID為IID_IUnknown=00000000-0000-0000-C000-000000000046。然后剩下就是用戶(hù)自己定義接口了。用戶(hù)也可以定義多個(gè)接口。最后提供服務(wù)的類(lèi)集成這些接口就組成了一個(gè)能夠被用來(lái)創(chuàng)建COM對(duì)象的類(lèi)了。比如下面的ICalc是一個(gè)接口,CCalc就是一個(gè)實(shí)現(xiàn)服務(wù)的類(lèi)。

1 class ICalc : public IUnknown 2 { 3 public: 4 virtual long __stdcall add(long a, long b) = 0; 5 virtual long __stdcall minus(long a, long b) = 0; 6 virtual long __stdcall times(long a, long b) = 0; 7 virtual long __stdcall devide(long a, long b) = 0; 8 }; 9 10 class CCalc : public ICalc 11 { 12 public: 13 CCalc(); 14 ~CCalc() = default; 15 16 public: 17 //IUnknown interface: 18 virtual HRESULT __stdcall QueryInterface(const IID &iid, void **ppv) override; 19 virtual ULONG __stdcall AddRef() override; 20 virtual ULONG __stdcall Release() override; 21 22 //ICalc interface: 23 virtual long __stdcall add(long a, long b) override; 24 virtual long __stdcall minus(long a, long b) override; 25 virtual long __stdcall times(long a, long b) override; 26 virtual long __stdcall devide(long a, long b) override; 27 28 private: 29 long m_lRef; 30 };

其中override是C++11標(biāo)準(zhǔn)所提供的關(guān)鍵字。
  這一篇博客就先寫(xiě)到這吧,后面還有需要繼續(xù)寫(xiě)的,但是現(xiàn)在要回寢室了,后續(xù)的明天或者后天繼續(xù)寫(xiě)。

PS:博主也是一個(gè)菜鳥(niǎo),最近才開(kāi)始寫(xiě)技術(shù)博客,如果各位發(fā)現(xiàn)了什么錯(cuò)誤,歡迎拍磚,指出錯(cuò)誤。

轉(zhuǎn)載于:https://www.cnblogs.com/DennisXie/p/3961648.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的《COM原理与应用》学习笔记二——COM对象和COM接口的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。