91无码视频一区|蜜臀福利在线观看|日韩一极黄色视频|色欲人妻少妇Av一区二区|婷婷香蕉视频欧美三级片黄色|一级A片刺激高潮|国产精品污污久久|日韩黄色精品日韩久久综合网|中国一级片电影在线|超碰乱码久久久免费

微軟的COM中GUID和UUID、CLSID、IID

2023-04-12


當(dāng)初微軟設(shè)計(jì)com規(guī)范的時(shí)候,有兩種選擇來(lái)保證用戶的設(shè)計(jì)的com組件可以全球唯一:


第一種是采用和Internet地址一樣的管理方式,成立一個(gè)管理機(jī)構(gòu),用戶如果想開(kāi)發(fā)一個(gè)COM組件的時(shí)候需要向該機(jī)構(gòu)提出申請(qǐng),并交一定的費(fèi)用。


第二種是發(fā)明一種算法,每次都能產(chǎn)生一個(gè)全球唯一的COM組件標(biāo)識(shí)符。


第一種方法,用戶使用起來(lái)太不方便,微軟采用第二種方法,并發(fā)明了一種算法,這種算法用GUID(Globally Unique Identifiers)來(lái)標(biāo)識(shí)COM組件,GUID是一個(gè)128位長(zhǎng)的數(shù)字,一般用16進(jìn)制表示。算法的核心思想是結(jié)合機(jī)器的網(wǎng)卡、當(dāng)?shù)貢r(shí)間、一個(gè)隨即數(shù)來(lái)生成GUID。從理論上講,如果一臺(tái)機(jī)器每秒產(chǎn)生10000000個(gè)GUID,則可以保證(概率意義上)3240年不重復(fù)。


GUID的例子: 54BF6567--1007--11D1--B0AA--444553540000


HKEY_CLASSES_ROOT\CLSID\{002B9E07-2E10-438F-AF1E-40E6A96F1EE4}


在微軟的COM中GUID和UUID、CLSID、IID是一回事,只不過(guò)各自代表的意義不同:


UUID : 代表COM


CLSID : 代表COM組件中的類


IID :代表COM組件中的接口


在程序中,實(shí)際對(duì)象數(shù)據(jù)對(duì)應(yīng)的處理程序路徑string往往不盡相同,比如有的放C盤(pán)有的D盤(pán),微軟想出了一個(gè)解決方案,那就是不使用直接的路徑表示方法,而使用一個(gè)叫 CLSID的方式間接描述這些對(duì)象數(shù)據(jù)的處理程序路徑。


CLSID 其實(shí)就是一個(gè)號(hào)碼,CLSID 的結(jié)構(gòu)定義如下:


typedef struct _GUID {
DWORD Data1; // 隨機(jī)數(shù)
WORD Data2; // 和時(shí)間相關(guān)
WORD Data3; // 和時(shí)間相關(guān)
BYTE Data4[8]; // 和網(wǎng)卡MAC相關(guān)
} GUID;


typedef GUID CLSID; // 組件ID
typedef GUID IID; // 接口ID
#define REFCLSID const CLSID &


// 常見(jiàn)的聲明和賦值方法
CLSID CLSID_Excel = {0x00024500,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
struct __declspec(uuid("00024500-0000-0000-C000-000000000046")) CLSID_Excel;
class DECLSPEC_UUID("00024500-0000-0000-C000-000000000046") CLSID_Excel;
// 注冊(cè)表中的表示方法
{00024500-0000-0000-C000-000000000046}


如果使用開(kāi)發(fā)環(huán)境編寫(xiě)組件程序,則IDE會(huì)自動(dòng)幫你產(chǎn)生 CLSID;


可以用函數(shù) CoCreateGuid() 產(chǎn)生 CLSID;


使用"vc目錄\Common\Tools\GuidGen.exe"工具產(chǎn)生GUID


每一個(gè)COM組件都需要指定一個(gè) CLSID,并且不能重名。它之所以使用16個(gè)字節(jié),就是要從概率上保證重復(fù)是“不可能”的。但是,微軟為了使用方便,也支持另一個(gè)字符串名稱方式,叫 ProgID。。由于 CLSID 和 ProgID 其實(shí)是一個(gè)概念的兩個(gè)不同的表示形式,所以我們?cè)诔绦蛑锌梢噪S便使用任何一種。
下面是 CLSID 和 ProgID 之間的轉(zhuǎn)換方法和相關(guān)的函數(shù):



函數(shù)


功能說(shuō)明


CLSIDFromProgID()、CLSIDFromProgIDEx()


由 ProgID 得到 CLSID。沒(méi)什么好說(shuō)的,你自己都可以寫(xiě),查注冊(cè)表貝


ProgIDFromCLSID()


由 CLSID 得到 ProgID,調(diào)用者使用完成后要釋放 ProgID 的內(nèi)存(注5)


CoCreateGuid()


隨機(jī)生成一個(gè) GUID


IsEqualGUID()、IsEqualCLSID()、IsEqualIID()


比較2個(gè)ID是否相等


StringFromCLSID()、StringFromGUID2()、StringFromIID()


由 CLSID,IID 得到注冊(cè)表中CLSID樣式的字符串,注意釋放內(nèi)存


客戶端軟件和組件之間的調(diào)用如下:



容器 協(xié)商部分


組件 應(yīng)答部分


1


根據(jù)CLSID啟動(dòng)組件 。


CoCreateInstance()


生成對(duì)象,執(zhí)行構(gòu)造函數(shù),執(zhí)行初始化動(dòng)作。


2


你有IUnknown接口嗎?


有,給你!


3


恩,太好了,那么你有IPersistStorage接口嗎?(注9)


IUnknown::QueryInterface(IID_IPersistStorage...)


沒(méi)有!


4


真差勁,連這個(gè)都沒(méi)有。那你有IPersistStreamInit接口嗎?(注10)


IUnknown::QueryInterface(IID_IPersistStreamInit...)


哈,這個(gè)有,給!


5


好,好,這還差不多。你現(xiàn)在給我初始化吧。


IPersistStreamInit::InitNew()


OK,初始化完成了。


6


完成了?好!現(xiàn)在你讀數(shù)據(jù)去吧。


IPersistStreamInit::Load()


讀完啦。我根據(jù)數(shù)據(jù),已經(jīng)在窗口中顯示出來(lái)了。


7


好,現(xiàn)在咱們各自處理用戶的鼠標(biāo)、鍵盤(pán)消息吧......


......


8


哎呀!用戶要保存退出程序了。你的數(shù)據(jù)被用戶修改了嗎?


IPersistStreamInit::IsDirty()


改了,用戶已經(jīng)修改啦。


9


那好,那么用戶修改后,你的數(shù)據(jù)需要多大的存儲(chǔ)空間呀?


IPersistStreamInit::GetSizeMax()


恩,我算算呀......好了,總共需要500KB。


10


暈,你這么個(gè)小玩意居然占用這么大空間?!......好了,你可以存了。


IPersistStreamInit::Save()


謝謝,我已經(jīng)存好了。


11


恩。拜拜了您那。(注11)


IPersistStreamInit::Release();IUnknown::Release()


執(zhí)行析構(gòu)函數(shù),刪除對(duì)象。


12


我自己也該退出了......


PostQuitMessage()





本文僅代表作者觀點(diǎn),版權(quán)歸原創(chuàng)者所有,如需轉(zhuǎn)載請(qǐng)?jiān)谖闹凶⒚鱽?lái)源及作者名字。

免責(zé)聲明:本文系轉(zhuǎn)載編輯文章,僅作分享之用。如分享內(nèi)容、圖片侵犯到您的版權(quán)或非授權(quán)發(fā)布,請(qǐng)及時(shí)與我們聯(lián)系進(jìn)行審核處理或刪除,您可以發(fā)送材料至郵箱:service@tojoy.com