日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

DLL接口的實現(xiàn)(虛函數(shù))

 imelee 2017-09-25

       我們在c++編程過程中往往要用到各種不同形式的程序庫,這些庫的發(fā)布方式有動態(tài)庫和靜態(tài)庫。對于靜態(tài)類庫,設計良好的靜態(tài)類庫能實現(xiàn)功能上的隔離,無法避免類庫實現(xiàn)必須重新編譯、鏈接整個應用程序的問題。而調用各種DLL動態(tài)庫成為我們程序員的家常便飯。

      以什么方式暴露庫的接口?可選的做法有:以全局(含 namespace 級別)函數(shù)為接口、以 class 的 non-virtual 成員函數(shù)為接口、以 virtual 函數(shù)為接口(interface)。本文主要講虛函數(shù)實現(xiàn)DLL接口和COM組件。

      虛函數(shù)實現(xiàn)接口的做法是定義一個頭文件,將類實現(xiàn)的接口聲明,可以將這個類的成員函數(shù)暴露給客戶。而接口的實現(xiàn)部分是在派生類中,用戶獲得頭文件中的接口,無需接口的實現(xiàn)就可以調用接口。往往我們會將這個接口類的成員定義為純虛函數(shù),這樣更直觀的體現(xiàn)派生類必須完成對接口的實現(xiàn)部分。

以下是代碼實例:

接口頭文件 IPerson.h

  1. #include<iostream>  
  2. #include<string>  
  3. using namespace std;  
  4.   
  5. #ifdef _EXPORTING  
  6. #define CLASS_DECLSPEC __declspec(dllexport)  
  7. #else  
  8. #define CLASS_DECLSPEC __declspec(dllimport)  
  9. #endif  
  10.   
  11. class IPerson  
  12. {  
  13. public:  
  14.     IPerson(){};  
  15.   
  16.     //接口  
  17.     virtual void  SetName(const string &strName) = 0;  
  18.     virtual const string GetName() = 0;  
  19.     virtual void  Work() = 0;  
  20. };  


       __declspec(dllexport)用于導出符號,也就是定義該函數(shù)的dll;__declspec(dllimport)用于導入,也就是使用該函數(shù)。因為這個頭文件既要被定義該函數(shù)的dll包含,也要被使用該函數(shù)的程序包含,當被前者包含時我們希望使用__declspec(dllexport)定義函數(shù),當被后者包含時我們希望使用dllimport。于是我們使用

         #ifdef _EXPORTING

         #define CLASS_DECLSPEC __declspec(dllexport)

         #else

         #define CLASS_DECLSPEC __declspec(dllimport)

         #endif

        這種技巧,在定義該函數(shù)的dll中,其編譯選項定義了_EXPORTING而使用該函數(shù)的程序則沒有定義。反正我們的頭文件是要暴露給用戶的,這樣定義可以保持DLL庫頭文件和用戶庫頭文件保持一致。

 

接口實現(xiàn)部分:CTeacher.cpp

  1. #include "IPerson.h"  
  2.   
  3. //定義接口  
  4. CLASS_DECLSPEC bool GetIPersonObject(void** _RtObject);  
  5.   
  6. class CTeacher:public IPerson  
  7. {  
  8. public:  
  9.     CTeacher(){}  
  10.     //接口實現(xiàn)  
  11.      void  SetName(const string &strName);  
  12.     const string GetName();  
  13.     void  Work();  
  14. private:  
  15.     string m_strName;  
  16. };  
  17.   
  18. void CTeacher::SetName(const string &strName)  
  19. {  
  20.     m_strName = strName;  
  21. }   
  22. const string CTeacher::GetName()  
  23. {  
  24.     return m_strName;  
  25. }  
  26. void CTeacher::Work()  
  27. {  
  28.     cout<<"I am teaching!"<<endl;  
  29. }  
  30.   
  31. bool GetIPersonObject(void **_RtObject)  
  32. {  
  33.     IPerson* pMan = NULL;  
  34.     pMan =  new CTeacher();  
  35.     *_RtObject = (void*)pMan;  
  36.     return true;  
  37. }  

          這樣,我們在工程->屬性->配置屬性->常規(guī)->配置類型 中選擇 動態(tài)庫(.dll)運行就可以生成對應的.dll和.lib。我們在客戶程序中就可以使用這個dll。具體做法如下:1.程序中包含接口的頭文件,即 IPerson.h      2.包含lib,在 工程->屬性->配置屬性->VC++目錄->庫目錄中加入.lib的文件目錄,在工程->屬性->配置屬性->連接器->輸入->附加依賴項中加入.lib  。

main.cpp

  1. #include "IPerson.h"  
  2.   
  3. #pragma comment(lib,"InterFace.lib")  
  4.   
  5. //導出接口  
  6. bool CLASS_DECLSPEC GetIPersonObject(void** _RtObject);  
  7.   
  8. void main()  
  9. {  
  10.     IPerson * _IPersonObj = NULL;  
  11.     void* pObj=NULL;  
  12.     if (GetIPersonObject(&pObj))          
  13.     {  
  14.         // 獲取對象  
  15.         _IPersonObj = (IPerson *)pObj;  
  16.         // 調用接口,執(zhí)行操作  
  17.         _IPersonObj->SetName("Tom");  
  18.             string strName = _IPersonObj->GetName();  
  19.         _IPersonObj->Work();  
  20.     }  
  21.     if (_IPersonObj !=NULL)  
  22.     {  
  23.         delete _IPersonObj ;  
  24.         _IPersonObj  = NULL;  
  25.     }  
  26. }  


輸出如下:

 

         到這里,一個簡單的虛函數(shù)實現(xiàn)DLL接口就做完了。有一點必須要說,設計庫的時候C++ 虛函數(shù)為接口是有弊端的?!耙坏┌l(fā)布,不能修改”。a)函數(shù)重名問題:我們通過函數(shù)名來調用DLL的函數(shù),在并行開發(fā)中 容易造成函數(shù)重名。b)依賴:如果采用常見的隱式連接,那DLL每發(fā)行了一個新版本都有 必要和應用程重新鏈接一次,因為DLL里面函數(shù)的地址可能已經(jīng)發(fā)生了改變。

        COM組件的思想正好解決了上述問題,下一節(jié)講COM組件思想的簡單實現(xiàn)。

 

 

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多