MSDN上沒(méi)有CoGetClassObject函數(shù)的源碼,資料上又說(shuō)CoGetClassObject調(diào)用DllGetClassObject函數(shù).不知這其中是如何調(diào)用地? //================= 查了一些資料 摘錄1如下: ---------- CoCreateInstance API函數(shù)將調(diào)用CoGetClassObject API,這個(gè)調(diào)用過(guò)程我們是看不到相關(guān)的代碼的,因?yàn)槲④浺呀?jīng)把他封裝好了。而CoGetClassObject函數(shù)的作用是什么呢?它將調(diào)用 LoadLibrary來(lái)尋找我們指定的COM組件(DLL),然后使用GetProcAddress 來(lái)尋找組件的入口函數(shù) - 其中的DllGetClassObject 函數(shù)就在這里將被調(diào)用。
摘錄2如下: ---------- CoGetClassObject及CoCreateInstance中都有對(duì)LoadLibrary和 GetProcAddress進(jìn)行調(diào)用。其中LoadLibrary的參數(shù)為DLL的名稱(chēng),而CoGetClassObject及 CoCreateInstance則使用它們的第一個(gè)參數(shù)(一個(gè)CLSID),組件可以用CLSID作為索引在Windows注冊(cè)表中發(fā)布包含它們的 DLL文件名稱(chēng)。CoGetClassObject及CoCreateInstance將用CLSID作為關(guān)鍵字在注冊(cè)表中查詢(xún)所需的DLL文件名稱(chēng)。 //================ 當(dāng)CoGetClassObject調(diào)用DllGetClassObject后,發(fā)現(xiàn)指針與句柄的關(guān)系就是(句柄是指針的指針) 從這倆個(gè)函數(shù)的參數(shù)就可以看出 STDAPI CoGetClassObject( REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO * pServerInfo, REFIID riid, LPVOID * ppv ); STDAPI DllGetClassObject( const CLSID & rclsid, const IID & riid, void ** ppv ); 具體函數(shù)例子: IClassFactory *classFactory; CoGetClassObject(&CLSID_IExample, CLSCTX_INPROC_SERVER, 0, &IID_IClassFactory, &classFactory)
HRESULT PASCAL DllGetClassObject(REFCLSID objGuid, REFIID factoryGuid, void **factoryHandle) { register HRESULT hr; if (IsEqualCLSID(objGuid, &CLSID_IExample)) { hr = classQueryInterface(&MyIClassFactoryObj, factoryGuid, factoryHandle); } else { *factoryHandle = 0; hr = CLASS_E_CLASSNOTAVAILABLE; } return(hr); }
CoGetClassObject中的參數(shù)&classFactory 與DllGetClassObject中的參數(shù)void **factoryHandle //===================== CoGetClassObject要加載DLL,但是我們并沒(méi)有給他傳遞DLL的路徑(DLL相關(guān)請(qǐng)參考DLL-使用DLL)。所以它要用參數(shù)clsid(即組件id,它是從CoCreateInstance傳遞過(guò)來(lái)的)去注冊(cè)表找到這個(gè)組件DLL路徑(請(qǐng)見(jiàn):COM筆記-Widows注冊(cè)表),然后把DLL加載起來(lái)。 加載起來(lái)之后我們就可以調(diào)用DLL的導(dǎo)出函數(shù)DllGetClassObject。并把clsid(組件ID),IID_IclassFactory(接口ID)傳遞它。(可以看一下DllGetClassObject的實(shí)現(xiàn),看看COM筆記-類(lèi)廠(chǎng)的源代碼)。 DllGetClassObject執(zhí)行成功則返回類(lèi)工廠(chǎng)接口pIFactory(見(jiàn)圖)。 接著就是 類(lèi)工廠(chǎng)接口pIFactory 調(diào)用 它的方法CreateInstance,去創(chuàng)建我們需要的組件,并返回我們需要的接口了。(同樣可以看看COM筆記-類(lèi)廠(chǎng)的源代碼) 關(guān)于參數(shù)punkonwnDuter這個(gè)沒(méi)用傳遞CoGetClassObject,而是傳遞給了類(lèi)廠(chǎng)的一個(gè)方法CreateInstance,主要是聚合方面的東西。(見(jiàn):COM筆記-包容與聚合) 參數(shù)dwClsContext限定所創(chuàng)建的組件的執(zhí)行上下文。(見(jiàn):COM筆記-CoCreateInstance)
|