小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

零基礎(chǔ)學(xué)習(xí)COM之COM庫(kù)和類廠介紹

 lpg2008 2013-12-11

       在windows系統(tǒng)中,注冊(cè)表是一個(gè)正式的共享系統(tǒng)數(shù)據(jù)庫(kù)。注冊(cè)表中包含關(guān)于系統(tǒng)軟硬件以及配置和用戶的各種信息。在COM技術(shù)中使用注冊(cè)表存儲(chǔ)關(guān)于組件的信息。客戶可以再注冊(cè)表中搜索它需要的組件。


    注冊(cè)表有許多關(guān)鍵字構(gòu)成的層次結(jié)構(gòu)。每個(gè)關(guān)鍵字又可以有一些列子關(guān)鍵字、以及值。使用regedit.exe可以編輯、查看注冊(cè)表。


    在注冊(cè)表HKEY_CLASSES_ROOT分支下有一個(gè)CLSID關(guān)鍵字。CLSID關(guān)鍵字下列有系統(tǒng)安裝的所有組件的CLSID。在CLSID下最重要的關(guān)鍵字是InprocServer32.此關(guān)鍵字的值是組件所在的DLL路徑名稱。由于使用CLSID來(lái)查看組件非常的麻煩,因此在每個(gè)CLSID關(guān)鍵字下都對(duì)應(yīng)著一個(gè)ProgID。它是程序員給某個(gè)CLSID指定的一個(gè)易記的名稱。但是ProgID不能保證唯一。


     ProgID主要作用是獲得相應(yīng)的CLSID。COM庫(kù)提供了兩個(gè)函數(shù)CLSIDFromProgID和ProgIDFromCLSID.來(lái)完成ProgID和CLSID之間的相互轉(zhuǎn)換。


    客戶可以在注冊(cè)表中查詢需要的組件。 但是注冊(cè)表中怎么存儲(chǔ)我們的組件信息呢?這是因?yàn)槊總€(gè)DLL都知道它所包含的組件。DLL可以將它所包含的組建信息注冊(cè)到注冊(cè)表中。因此在每個(gè)包含組件的DLL中,我們必須要輸出以下兩個(gè)函數(shù):


    

  1. extern "C" HRESULT _stdcall DllRegisterServer()  
  2.   
  3. extern "C" HRESULT _stdcall DllUnregisterServer()。  


 


    這兩個(gè)函數(shù)并不需要客戶直接調(diào)用,而是提供給COM庫(kù)調(diào)用的。COM會(huì)自動(dòng)搜索這兩個(gè)函數(shù)并調(diào)用。在許多程序的安裝過(guò)程中大多數(shù)安裝程序都會(huì)調(diào)用DllRegisterServer完成組件的注冊(cè)。用戶也可以使用程序REGSVR32.exe來(lái)手動(dòng)注冊(cè)某個(gè)組件。RegSvr32實(shí)際上上是通過(guò)調(diào)用上述兩個(gè)函數(shù)來(lái)完成組件注冊(cè)的。


    DllRegisterServer和DllUnregister是組件的生產(chǎn)者提供的,通過(guò)調(diào)用注冊(cè)表函數(shù)來(lái)在注冊(cè)表中添加某些項(xiàng)目。


    有關(guān)的注冊(cè)表函數(shù)為:
     

  1. RegOpenKeyEx,  
  2.      RegCreateKeyEx,  
  3.      RegSetValueEx,  
  4.      RegEnumKeyEx,  
  5.      RegDeleteKey,  
  6.      RegClosekey.  



   組件類別實(shí)際上就是一個(gè)接口集合。每個(gè)組件類別都有一個(gè)GUID。此時(shí)的GUID被稱為CATID(category ID)。對(duì)于某個(gè)組件,如果它實(shí)現(xiàn)了某個(gè)組件類別的所有接口,那么它就可以注冊(cè)為該組件類別的一個(gè)成員。這樣,客戶就能夠通過(guò)從注冊(cè)表中選擇只屬于某個(gè)特定組件類別的組件中準(zhǔn)確找到所需的組件。


    COM庫(kù)函數(shù)提供一一組對(duì)COM對(duì)象操作的函數(shù)。它們是在OLE32.DLL中實(shí)現(xiàn) 。
首先介紹COM的初始化函數(shù)。因?yàn)樵谑褂闷渌瘮?shù)之前必須調(diào)用CoInitialize來(lái)初始化COM庫(kù)。不再使用COM庫(kù)時(shí)必須調(diào)用CoUninitialize。對(duì)每個(gè)COM庫(kù)只需初始化一次。COM庫(kù)的初始化一般在客戶代碼中進(jìn)行。在提供組件的dll中則不需進(jìn)行。

    COM庫(kù)可以提供給用戶一個(gè)內(nèi)存分配器。使用此分配器組件可以給客戶提供一塊內(nèi)存。該內(nèi)存可以由用戶刪除。
CoGetMalloc返回一個(gè)內(nèi)存分配器IMalloc??梢允褂肐Malloc::Alloc申請(qǐng)一塊內(nèi)存。使用IMalloc::Free釋放。上述過(guò)程比較麻煩。因此COM庫(kù)實(shí)現(xiàn)了一些方便的幫助函數(shù)如CoTaskMemAlloc和CoTaskMemFree.它們分別完成內(nèi)存申請(qǐng)和釋放的過(guò)程。不再需要先獲得內(nèi)存分配器在申請(qǐng)和釋放內(nèi)存。


    在注冊(cè)表中包含的CLSID是以字符串形式表示的。因此需要一些函數(shù)完成CLSID與字符串之間的轉(zhuǎn)換。如:

  

  

  1. StringFromGUID2,  
  2. StringFromCLSID,  
  3.   
  4.  StringFromIID,  
  5.   
  6. CLSIDFromString,IIDFromString。  


     前面我們介紹了使用CreateInstance來(lái)創(chuàng)建組建對(duì)象的例子。但是那是我們自己定義的函數(shù)。實(shí)際上在COM庫(kù)中也提供了專門創(chuàng)建COM對(duì)象的函數(shù):CoCreateInstance。此函數(shù)也是創(chuàng)建COM對(duì)象最簡(jiǎn)單的方式。但是CoCreateInstance卻不太靈活。在此情況下引入了類廠。

    所有的組件都是通過(guò)類廠來(lái)創(chuàng)建的,客戶使用類廠來(lái)創(chuàng)建對(duì)象有很大的靈活性。

    CoCreateInstance函數(shù):

 

  1. <span style="font-size:18px;">HRESULT _stdcall CoCreateInstance(  
  2.   
  3. CLSID &clsid,  
  4.   
  5. IUnknown *pIUnknownOuter,  
  6.   
  7. DWORD dwClsContext,  
  8.   
  9. Const IID&iid,  
  10.   
  11. Void **ppv);  
  12.   
  13. </span>  


 

    clsid標(biāo)識(shí)一個(gè)想要?jiǎng)?chuàng)建的組件。

    iid標(biāo)識(shí)此組件的一個(gè)接口,ppv返回接口指針。此函數(shù)可以在創(chuàng)建COM對(duì)象的同時(shí)返回該對(duì)象的相應(yīng)接口指針。

    dwClsContext限定所創(chuàng)建的組件的執(zhí)行上下文。

    pIUnknownOuter用于組件聚合,稍后會(huì)有介紹。

 

  1. <span style="font-size:18px;"> HRESULT hr=CoCreateInstance(CLSID_CA,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,(void**)&pI);  
  2.   
  3.  if(!SUCCEEDED(h))  
  4.   
  5.  {  
  6.   
  7.    pI->IY_Func();  
  8.   
  9.    pI->Release();  
  10.   
  11.  }  
  12.   
  13. </span>  


 

   CLSCTX_INPROC_SERVER告訴CoCreateInstance要加載的是進(jìn)程中服務(wù)器或dll中的組件。

    CoCreateInstance的第三個(gè)參數(shù)控制所創(chuàng)建的組件是在與客戶相同的進(jìn)程中運(yùn)行,還是在不同的進(jìn)程中運(yùn)行或者是在另一臺(tái)機(jī)器上運(yùn)行。

此參數(shù)可以是一下值:

     CLSCTX_INPROC_SERVER 客戶希望在同一進(jìn)程創(chuàng)建組建。此組件必須在dll中實(shí)現(xiàn)。

     CLSCTX_INPROC_HANDLER客戶希望創(chuàng)建進(jìn)程中處理器。所謂進(jìn)程中處理器實(shí)際上是只實(shí)現(xiàn)了某個(gè)組件的一部分的進(jìn)程中組件

     CLSCTX_LOCAL_SERVER 客戶希望創(chuàng)建一個(gè)在同一機(jī)器的另外一個(gè)進(jìn)程中運(yùn)行的組件。

     CLSCTX_REMOTE_SERVER 客戶希望創(chuàng)建一個(gè)在遠(yuǎn)程機(jī)器上運(yùn)行的組件。

   客戶可以在三種不同的進(jìn)程上下文中使用某個(gè)組件:進(jìn)程中、本地及遠(yuǎn)程。

    下面的例子創(chuàng)建了純COM客戶和組件

  1. <span style="font-size:18px;">int main(int argc,char**argv)  
  2.   
  3. {  
  4.   
  5. CoInitialize();  
  6.   
  7. IX*pIX=NULL;  
  8.   
  9. HRESULT hr=CoCreateInstance(CLSID_CA,NULL,CLSCTX_INPROC_SERVER,IID_IX,(void**)&pIX);  
  10.   
  11.   
  12.     if(SUCCEEDED(hr)  
  13.   
  14.    {  
  15.   
  16.       pIX->IX_Func();  
  17.   
  18.   
  19.      IY*pIY=NULL;  
  20.   
  21.      hr=pIX->QueryInterface(IID_IY,(void**)&pIY);  
  22.   
  23.      pIX->Release();  
  24.   
  25.      if(SUCCEEDED(hr))  
  26.   
  27.      {  
  28.   
  29.         pIY->IY_Func();  
  30.   
  31.        pIY->Release();  
  32.   
  33.      }  
  34.   
  35.   }  
  36.   
  37.   
  38.   CoUninitialize();  
  39.   
  40.   return 0;  
  41.   
  42. }  
  43.   
  44. </span>  


 

    前面我們提到過(guò)使用CoCreateInstance創(chuàng)建對(duì)象不太靈活,那么接下來(lái)我們將介紹更加靈活的創(chuàng)建方式:使用類廠。

    首先介紹COM庫(kù)的CoGetClassObject,它接受一個(gè)標(biāo)識(shí)組件的CLSID,并返回相應(yīng)類廠中某個(gè)接口指針函數(shù)。

  1. <span style="font-size:18px;">HRESULT _stdcall CoGetClassObject(  
  2.   
  3.      Const CLSID&clsid,  
  4.   
  5.      DWORD dwClsContext,  
  6.   
  7.      COSERVERINFO*pServerInfo,  
  8.   
  9.      Const IID&iid,  
  10.   
  11.      Void **ppv);    
  12.   
  13. </span>  


 

    可以看到該函數(shù)與CoCreateInstance的參數(shù)很類似。它們的第一個(gè)參數(shù)都是待創(chuàng)建的組件的CLSID。第二個(gè)參數(shù)均為創(chuàng)建組件的上下文。pServerInfo將被DCOM用于對(duì)遠(yuǎn)程組件的訪問(wèn)。

     但最大的差別在于CoGetClassObject返回的是創(chuàng)建組件的類廠的接口指針,而不是指向組件的接口指針。

    客戶可以調(diào)用CoGetClassObject的返回的指針來(lái)創(chuàng)建相應(yīng)的組件。該指針通常是一個(gè)IClassFactory指針。

IClassFactory接口聲明如下:

  1. <span style="font-size:18px;">class IClassFactory:public IUnknown  
  2.   
  3. {  
  4.   
  5. public:  
  6.   
  7.  HRESULT _stdcall CreateInstance(  
  8.   
  9.         IUnknown*pUnknownOuter,  
  10.   
  11.         Const IID&iid,  
  12.   
  13.         Void **ppv);  
  14.   
  15.  HRESULT _stdcall LockServer  
  16.   
  17. };  
  18.   
  19. </span>  


 

它有兩個(gè)成員函數(shù):

    CreateInstance第一個(gè)參數(shù)為指向某個(gè)IUnknown接口的指針,同CoCreateInstanceIUnknown指針是相同的,也是用于組件聚合。最后兩個(gè)的參數(shù)與QueryInterface的參數(shù)是相同的。

但是CreateInstance沒(méi)有接受標(biāo)識(shí)要?jiǎng)?chuàng)建組件的CLSID,那么它如何獲得要?jiǎng)?chuàng)建組件的CLSID呢?大家可以看下CoGetClassObject。它接受一個(gè)標(biāo)識(shí)組件的CLSID。哦,原來(lái)如此??!

    其實(shí)在前面介紹過(guò)的CoCreateInstance ,它在實(shí)現(xiàn)時(shí)使用了CoGetClassObjectCreateInstance。雖然使用CoCreateInstance函數(shù)靈活性不好,但是很簡(jiǎn)單。在滿足需要的前提下此函數(shù)經(jīng)常被使用。接下來(lái)看一下CoCreateInstance的實(shí)現(xiàn):

  1. HRESULT _stdcall CoCreateInstance(  
  2.   
  3.                 const CLSID&clsid,  
  4.   
  5.                IUnknown*pUnknownOuter,  
  6.   
  7.                DWORD dwClsContext,  
  8.   
  9.                const IID&iid,  
  10.   
  11.                void **ppv)  
  12.   
  13. {  
  14.   
  15.      IClassFactory pIFactroy=NULL;  
  16.   
  17.     HRESULT hr=CoGetClassObject(clsid,dwClsContext,NULL,IID_CLASSFACTORY,(void**)&pIFactroy);  
  18.   
  19.    if(SUCCEEDED(hr))  
  20.   
  21.    {  
  22.   
  23.   
  24.       pIFactroy->CreateInstance(pUnknownOuter,IID_IX,ppv);  
  25.   
  26.       pIFactroy->Release();  
  27.   
  28.       pIX->IX_Func();  
  29.   
  30.      pIX->Release();  
  31.   
  32.    }  
  33.   
  34.   
  35. }  


 

    大多數(shù)情況下組件的創(chuàng)建都是使用CoCreateInstance而不是CoGetClassObject。但是當(dāng)創(chuàng)建一個(gè)組件的多個(gè)實(shí)例時(shí)使用CoGetClassObject具有很提高的效率。因?yàn)榇藭r(shí)并不需要?jiǎng)?chuàng)建多個(gè)類廠。一個(gè)類廠完成所有組件實(shí)例的創(chuàng)建。

DllGetClassObject 完成類廠的創(chuàng)建。此函數(shù)被CoGetClassObject調(diào)用。

  1. <span style="font-size:18px;">STDAPI  DllGetClassObject(  
  2.   
  3.      Const CLSID&clsid,  
  4.   
  5.      Const IID&iid,  
  6.   
  7.      Void **ppv);  
  8.   
  9. </span>  


    此函數(shù)的三個(gè)參數(shù)與CoGetClassObject相同。

接下來(lái)我們完整的介紹下組件的創(chuàng)建過(guò)程:

     首先,客戶調(diào)用COM庫(kù)函數(shù)CoGetClassObject,此函數(shù)調(diào)用組件內(nèi)提供的函數(shù)DllGetClassObject完成類廠的創(chuàng)建并返回類廠指針,然后使用類廠指針調(diào)用COM庫(kù)IClassFactory::CreateInstance創(chuàng)建組件對(duì)象并返回接口指針。

    可以注意到dll中導(dǎo)出四個(gè)函數(shù)。它們分別是:

     

  1. DllGetClassObject,  
  2.   
  3.  DllCanUnloadNow,  
  4.   
  5. DllReigisterServer,  
  6.   
  7. DllUnregisterServer。  


     前面提到過(guò)可以在一個(gè)dll中實(shí)現(xiàn)多個(gè)組件。之所以可以實(shí)現(xiàn)這一點(diǎn)就是因?yàn)閷?dǎo)出函數(shù):DllGetClassObject。它能夠根據(jù)不同的CLSID,創(chuàng)建對(duì)應(yīng)的類廠。一個(gè)DLL可以支持多個(gè)組件也從側(cè)面說(shuō)明了DLL并不等價(jià)于組件,而是相當(dāng)于一個(gè)組件服務(wù)器。

    DLL的卸載

    DllCanUnloadNowLockServer

    DLL內(nèi)可以有多個(gè)組件。為了使DLL在所有組件都不使用后被卸載,需要在dll內(nèi)維護(hù)一個(gè)當(dāng)前可用組件的計(jì)數(shù)g_NumOfCom;當(dāng)此值為0時(shí)說(shuō)明沒(méi)有對(duì)象正在被使用,dll就可以被卸載了。g_NumCom會(huì)在組件的構(gòu)造函數(shù)或IClassFactory::CreateInstance中被增加,在組件的析構(gòu)函數(shù)中減小。

    LockServerIClassFactory的成員函數(shù),它對(duì)鎖計(jì)數(shù)器進(jìn)行操作。當(dāng)鎖計(jì)數(shù)器大于0時(shí),可以防止該類廠所占空間被釋放掉。假設(shè)客戶擁有一個(gè)指向某類廠的指針,在某個(gè)DLL被卸載后,該類廠對(duì)應(yīng)的空間被釋放掉,類廠指針就變成了一個(gè)野指針,使用時(shí)會(huì)造成違規(guī)訪問(wèn)。

    初始時(shí)鎖計(jì)數(shù)器為0,LockServer(true)會(huì)使鎖計(jì)數(shù)器加一,此時(shí)類廠對(duì)象被鎖住,保留在內(nèi)存中不被釋放,使用完畢后再次調(diào)用此函數(shù)解鎖。

LockServer(false)會(huì)使鎖計(jì)數(shù)器的值減一。

    DllCanUnloadNow可以返回該DLL是否可以被卸載。若現(xiàn)在沒(méi)有組件在被使用,那么此時(shí)該DLL就可以從內(nèi)存中撤銷了。

    組件個(gè)數(shù)和鎖計(jì)數(shù)器可以使用同一個(gè)數(shù)值g_NumOfCom,也可以分別使用。當(dāng)使用不同的值時(shí)在DllCanUnloadNow中就必須對(duì)這兩個(gè)值進(jìn)行判斷,只有當(dāng)它們都為0時(shí),dll才能被卸載。

     Win7下調(diào)用RegCreateKeyExHKEY_CLASSES_ROOT添加鍵,需要在程序運(yùn)行時(shí)獲得管理員權(quán)限。否則返回值為5,權(quán)限不足。

下面的代碼綜合了前面介紹的所有知識(shí),是一個(gè)相對(duì)比較完整的例子:

  1. <span style="font-size:18px;">IX.h  
  2. #include"objbase.h"  
  3. class IX:public IUnknown  
  4. {  
  5. public:  
  6.     virtual void IX_Func()=0;  
  7. };</span>  

  1. <span style="font-size:18px;">//IY.h  
  2. #include"objbase.h"  
  3. class IY:public IUnknown  
  4. {  
  5. public:  
  6.     virtual void IY_Func()=0;  
  7. };</span>  

  1. <span style="font-size:18px;">//CA.h  
  2. #ifndef CA_H  
  3. #define CA_H  
  4. #include<iostream>  
  5. #include"IX.h"  
  6. #include"IY.h"  
  7. extern UINT g_NumOfCom;  
  8. class CA:public IX,public IY  
  9. {  
  10. public:  
  11.     CA()  
  12.     {  
  13.         m_Ref=0;  
  14.         g_NumOfCom++;  
  15.         std::cout<<"CA構(gòu)造函數(shù)被調(diào)用??!"<<std::endl;  
  16.     }  
  17.     ~CA()  
  18.     {  
  19.         std::cout<<"CA析構(gòu)函數(shù)被調(diào)用??!"<<std::endl;  
  20.         g_NumOfCom--;  
  21.     }  
  22.     HRESULT _stdcall QueryInterface(const IID&id,void **ppv);  
  23.     ULONG _stdcall AddRef();  
  24.     ULONG _stdcall Release();  
  25.   
  26.     void IX_Func();  
  27.     void IY_Func();  
  28. public:  
  29.     ULONG m_Ref;  
  30. };  
  31. #endif</span>  

  1. <span style="font-size:18px;">//CA.cpp  
  2. #include"StdAfx.h"  
  3. #include"CA.h"  
  4. extern IID IID_IX;  
  5. extern IID IID_IY;  
  6. // {AB4B7F96-B8A5-4BB3-BF44-8FB158ED36AD}  
  7.   
  8. extern IID IID_CA;  
  9. HRESULT  CA::QueryInterface(const IID&id,void**ppv)  
  10. {  
  11.     std::cout<<"CA::QueryInterface被調(diào)用!!"<<std::endl;  
  12.     if(id==IID_IUnknown)  
  13.     {  
  14.         *ppv=static_cast<IX*>(this);  
  15.     }  
  16.     else if(id==IID_IX)  
  17.     {  
  18.         *ppv=static_cast<IX*>(this);  
  19.     }  
  20.     else if(id==IID_IY)  
  21.     {  
  22.         *ppv=static_cast<IY*>(this);  
  23.     }  
  24.     else  
  25.     {  
  26.         *ppv=NULL;  
  27.         return E_NOINTERFACE;  
  28.     }  
  29.     static_cast<IUnknown*>(*ppv)->AddRef();  
  30.     return S_OK;  
  31. };  
  32. ULONG CA::AddRef()  
  33. {  
  34.     std::cout<<"CA::Addref被調(diào)用!!"<<std::endl;  
  35.     m_Ref++;  
  36.     return m_Ref;  
  37. }  
  38. ULONG CA::Release()  
  39. {  
  40.     std::cout<<"CA:release被調(diào)用!!"<<std::endl;  
  41.     if(--m_Ref==0)  
  42.     {  
  43.         delete this;  
  44.     }  
  45.     return m_Ref;  
  46. }  
  47. void CA::IX_Func()  
  48. {  
  49.     std::cout<<"IX_Func被調(diào)用?。?<<std::endl;  
  50. }  
  51. void CA::IY_Func()  
  52. {  
  53.     std::cout<<"IY_Func被調(diào)用??!"<<std::endl;  
  54. }</span>  

  1. <span style="font-size:18px;">//CFactory.h  
  2. #include<objbase.h>  
  3.   
  4. class CFactory:public IClassFactory  
  5. {  
  6. public:  
  7.     CFactory();  
  8.     ~CFactory();  
  9.     HRESULT _stdcall CreateInstance(IUnknown*pUnknownOuter,const IID&iid,void **ppv);  
  10.     HRESULT _stdcall LockServer( BOOL fLock);  
  11.     HRESULT _stdcall QueryInterface(const IID&iid,void**ppv);  
  12.     ULONG _stdcall AddRef();  
  13.     ULONG _stdcall Release();  
  14. private:  
  15.     LONG m_Ref;  
  16. };  
  17.   
  18. </span>  

  1. <span style="font-size:18px;">//CFactory.cpp  
  2. #include"stdafx.h"  
  3. #include"CFactory.h"  
  4. #include"CA.h"  
  5. // {186E5F66-438C-49EF-B8E3-29BB2B8CC133}  
  6.   
  7.   
  8. extern UINT g_NumOfCom;  
  9.  extern GUID CLSID_FACTORY;  
  10. UINT g_ServerLocks=0;  
  11. HRESULT _stdcall CFactory::CreateInstance(IUnknown*pUnknownOuter,const IID&iid,void **ppv)  
  12. {  
  13.     std::cout<<"CFactory::CreateInstance被調(diào)用??!"<<std::endl;  
  14.     if(pUnknownOuter)  
  15.     {  
  16.         return CLASS_E_NOAGGREGATION;  
  17.     }  
  18.     CA*pCA=new CA;  
  19.     if(!pCA)  
  20.     {  
  21.         std::cout<<"new CA申請(qǐng)失敗?。?<<std::endl;  
  22.         return E_OUTOFMEMORY;  
  23.     }  
  24.     std::cout<<"new CA創(chuàng)建成功?。?!"<<std::endl;  
  25.     HRESULT hr=pCA->QueryInterface(iid,ppv);  
  26.     pCA->Release();  
  27.     return hr;  
  28.   
  29. }  
  30. HRESULT _stdcall CFactory::QueryInterface( const IID&iid,void**ppv )  
  31. {  
  32.     std::cout<<"CFactory::QueryInterface被調(diào)用!!"<<std::endl;  
  33.     //if(iid==IID_IUnknown||iid==CLSID_FACTORY)  
  34.     //if()  
  35.     {  
  36.         *ppv=static_cast<IClassFactory*>(this);  
  37.     }  
  38.     //else  
  39.     {  
  40.         //*ppv=NULL;  
  41.         //std::cout<<"CFactory:接口查詢失?。?!"<<std::endl;  
  42.         //return E_NOINTERFACE;  
  43.     }  
  44.     static_cast<IUnknown*>(*ppv)->AddRef();  
  45.     return S_OK;  
  46. }  
  47.   
  48. ULONG _stdcall CFactory::AddRef()  
  49. {  
  50.     std::cout<<" CFactory::AddRef被調(diào)用!!"<<std::endl;  
  51.     m_Ref++;  
  52.     return m_Ref;  
  53. }  
  54.   
  55. ULONG _stdcall CFactory::Release()  
  56. {  
  57.     std::cout<<"CFactory::Release被調(diào)用!!"<<std::endl;  
  58.     if(--m_Ref==0)  
  59.     {  
  60.         delete this;  
  61.     }  
  62.     return m_Ref;  
  63. }  
  64.   
  65. CFactory::CFactory()  
  66. {  
  67.     std::cout<<"CFactory構(gòu)造函數(shù)被調(diào)用?。?<<std::endl;  
  68.     m_Ref=1;  
  69.     g_NumOfCom++;  
  70. }  
  71.   
  72. HRESULT _stdcall CFactory::LockServer( BOOL fLock )  
  73. {  
  74.     if(fLock)  
  75.     {  
  76.         g_ServerLocks++;  
  77.     }  
  78.     else  
  79.     {  
  80.         g_ServerLocks--;  
  81.     }  
  82.     return S_OK;  
  83. }  
  84.   
  85. CFactory::~CFactory()  
  86. {  
  87.     std::cout<<"CFactory析構(gòu)函數(shù)被調(diào)用??!"<<std::endl;  
  88.     g_NumOfCom--;  
  89. }  
  90. </span>  

  1. <span style="font-size:18px;">//dll.DEF  
  2. ;LIBRARY "dll.dll"   
  3. EXPORTS  
  4.     DllGetClassObject  PRIVATE  
  5.     DllCanUnloadNow  PRIVATE</span>  

  1. <span style="font-size:18px;">//dll.h  
  2. // 下列 ifdef 塊是創(chuàng)建使從 DLL 導(dǎo)出更簡(jiǎn)單的  
  3. // 宏的標(biāo)準(zhǔn)方法。此 DLL 中的所有文件都是用命令行上定義的 DLL_EXPORTS  
  4. // 符號(hào)編譯的。在使用此 DLL 的  
  5. // 任何其他項(xiàng)目上不應(yīng)定義此符號(hào)。這樣,源文件中包含此文件的任何其他項(xiàng)目都會(huì)將  
  6. // DLL_API 函數(shù)視為是從 DLL 導(dǎo)入的,而此 DLL 則將用此宏定義的  
  7. // 符號(hào)視為是被導(dǎo)出的。  
  8. #ifdef DLL_EXPORTS  
  9. #define DLL_API __declspec(dllexport)  
  10. #else  
  11. #define DLL_API __declspec(dllimport)  
  12. #endif  
  13. #include"objbase.h"  
  14.  DllCanUnloadNow(void);  
  15.  DLL_API STDAPI DllGetClassObject(const CLSID&clsid,const IID&iid,void**ppv);  
  16.  extern "C" DLL_API HRESULT DllRegisterServer();  
  17.  extern "C" DLL_API HRESULT  DllUnregisterServer(); </span>  
  1. <pre class="cpp" name="code"><span style="font-size:18px;">// dllmain.cpp :   
  2. 定義 DLL 應(yīng)用程序的入口點(diǎn)。  
  3. #include "stdafx.h"  
  4. extern HMODULE g_DLLModule;  
  5. BOOL APIENTRY DllMain( HMODULE hModule,  
  6.                        DWORD  ul_reason_for_call,  
  7.                        LPVOID lpReserved  
  8.                      )  
  9. {  
  10.     switch (ul_reason_for_call)  
  11.     {  
  12.     case DLL_PROCESS_ATTACH:  
  13.         g_DLLModule=hModule;  
  14.     case DLL_THREAD_ATTACH:  
  15.     case DLL_THREAD_DETACH:  
  16.     case DLL_PROCESS_DETACH:  
  17.         break;  
  18.     }  
  19.     return TRUE;  
  20. }  
  21. </span></pre>  
  22. <pre></pre>  
  23. <pre class="cpp" name="code"><span style="font-size:18px;">//GUID.cpp  
  24. #include"StdAfx.h"  
  25.  IID IID_IUnknown =   
  26. { 0x49fa8f03, 0x1ab0, 0x4d75, { 0xb0, 0x23, 0x54, 0xb7, 0xf, 0xa7, 0x31, 0xc2 } };  
  27.   
  28. IID IID_IX =   
  29. { 0x8af3709f, 0xa8eb, 0x46c4, { 0xb5, 0x1, 0xbc, 0xb6, 0x7d, 0x45, 0x9a, 0xfe } };  
  30. IID IID_IY =   
  31. { 0xc18d13a4, 0x57af, 0x41d7, { 0xb5, 0xf2, 0x46, 0xc1, 0xfe, 0xa6, 0xbc, 0x37 } };  
  32. CLSID CLSID_CA =   
  33. { 0xab4b7f96, 0xb8a5, 0x4bb3, { 0xbf, 0x44, 0x8f, 0xb1, 0x58, 0xed, 0x36, 0xad } };  
  34. CLSID CLSID_FACTORY =   
  35. { 0x186e5f66, 0x438c, 0x49ef, { 0xb8, 0xe3, 0x29, 0xbb, 0x2b, 0x8c, 0xc1, 0x33 } };</span></pre><pre class="cpp" name="code"></pre><pre class="cpp" name="code"></pre>  
  36. <pre></pre>  

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多