久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C/C++ (函數(shù),、變量和類)動態(tài)庫的創(chuàng)建,、導(dǎo)出和使用

 imelee 2017-09-26

Windows

 1引入庫的原因:

   a.項目的復(fù)雜程度大

   b.提高代碼的利益利用率

 2庫的分類

   2.1靜態(tài)庫: *.lib,,不能被加載的程序,,可以理解為目標(biāo)程序的歸檔,。

2.2動態(tài)庫:*.dll,,可以被應(yīng)用程序加載的程序,。

 

 二 動態(tài)庫

1動態(tài)庫優(yōu)點

 1.1可以提供模塊化的方式,方便協(xié)調(diào)開發(fā)(對于大項目,,每個人寫的東西編譯為動態(tài)庫,,直接鏈接即可)

 1.2對源代碼保護

 1.3減小可執(zhí)行文件大小

 1.4提高代碼重用率


2動態(tài)庫的基本使用方法

 2.1動態(tài)庫的創(chuàng)建

 2.2加載動態(tài)庫

 2.3獲取并使用庫函數(shù)、變量或類

 2.4釋放動態(tài)庫


3動態(tài)庫的函數(shù)

 3.1動態(tài)庫的創(chuàng)建

   3.1.1創(chuàng)建DLL項目

     創(chuàng)建Win32Dll項目,,創(chuàng)建DLL項目,添加*.cpp文件,。

  


  

3.1.2增加動態(tài)庫函數(shù)


    3.1.3導(dǎo)出動態(tài)庫函數(shù)(告訴使用者動態(tài)庫中可提供的函數(shù),代碼示例如上)


     (1)使用__declspec(dllexport)方式,在函數(shù)前增加關(guān)鍵字,。舉例如下:

  1. __declspec(dllexport) intDll_Add(intnLeft,intnRight){  
  2.   
  3.       return(nLeft + nRight);  
  4.   
  5. }//C++方式導(dǎo)出  

     (2)增加extern “C”方式,舉例如下

  1. extern"C" __declspec(dllexport)//  以C語言方式導(dǎo)出函數(shù)  

                    (3)使用def方式導(dǎo)出(在項目中添加*.def文件)


 //*.def文件中信息


   LIBRARY dllfunc.dll //導(dǎo)出庫


   EXPORTS        //導(dǎo)出表


     Dll_Mul @1   //導(dǎo)出函數(shù)


     Dll_Div @2

 (VC6中def導(dǎo)出方式與 extern “C”導(dǎo)出方式導(dǎo)出.lib文件內(nèi)容基本相同,,可用于顯式鏈接)

 

  動態(tài)庫導(dǎo)出函數(shù)代碼示例如下:

  1. #include<Windows.h>  
  2. #include <iostream>  
  3.   
  4. using namespace std;  
  5.   
  6. BOOL WINAPI DllMain(//返回值代表是否記載成功  
  7.     HINSTANCE hinstDll,//DLL句柄  
  8. DWORD   fdwReason,//DLL被調(diào)用的原因  
  9. LPVOID  lpvReserved)//保留值  
  10. {  
  11.     cout << "DLL = " << hinstDll << endl;  
  12.     cout << "fdwReason = " << fdwReason << endl;  
  13.     return TRUE;      
  14. }  
  15.   
  16.   
  17.   
  18. //C++導(dǎo)出方式  
  19. extern "C" __declspec (dllexport)  int Dll_Add(int nLeft, int nRight)  
  20. {  
  21.     return (nLeft + nRight);  
  22. }  
  23.   
  24.   
  25. //C的導(dǎo)出方式  
  26. extern "C"__declspec (dllexport)  int Dll_Sub(int nLeft, int nRight)  
  27. {  
  28.     return (nLeft - nRight);  
  29. }  
  30.   
  31. //DEF導(dǎo)出方式  
  32.   
  33. int Dll_Mul(int nLeft, int nRight)  
  34. {  
  35.     return (nLeft * nRight);  
  36. }  

    3.2 使用

   3.2.1隱式鏈接


     (1)導(dǎo)入lib


      a.在項目屬性->鏈接器->輸入->附加依賴項中設(shè)置即可。


      b.使用#pragma導(dǎo)入,,舉例如下:


 

  1. #pragma comment (lib,"../lib/Dll_Func.lib")  

      

    (2) 定義函數(shù)原型

        聲明一個和導(dǎo)出函數(shù)一致的函數(shù)原型,,如下所示:

  1. #pragma comment (lib,"../lib/Dll_Func.lib")  
  2.   
  3.  extern "C" int  Dll_Add(int nLeft, int nRight);  
  4.  extern "C" int  Dll_Sub(int nLeft, int nRight);  

   

    (3) 使用函數(shù)(注意:生成.dll文件最好與調(diào)用其的.exe文件在同一個目錄)

        直接使用函數(shù)即可,示例代碼如下:

  1. #include <cstdio>  
  2.   
  3. #pragma comment (lib,"../lib/Dll_Func.lib")  
  4.   
  5. extern "C" int  Dll_Add(int nLeft, int nRight);  
  6. extern "C" int  Dll_Sub(int nLeft, int nRight);  
  7. int Dll_Mul(int nLeft, int nRight);  
  8. int main()  
  9. {  
  10.     int nAdd = Dll_Add(100, 100);  
  11.     int nSub = Dll_Sub(100, 100);  
  12.     int nMul = 0;//Dll_Mul(100, 100);  
  13.     printf("nAdd = %d\n", nAdd);  
  14.     printf("nSub = %d \n", nSub);  
  15.     printf("nMul = %d \n", nMul);  
  16.     return 0;  
  17. }  

        (4) 應(yīng)用程序查找Dll路徑(最好將要調(diào)用的動態(tài)庫與調(diào)用動態(tài)庫的.exe文件放在同一目錄下)

        A查找當(dāng)前應(yīng)用程序的目錄


        B當(dāng)前工作目錄


        C查找Windows System32目錄


        D查找Windows System的目錄


        E查找Windows目錄


        F查找環(huán)境變量Path指定的目錄


   3.2.2顯式鏈接

     (1)加載動態(tài)庫

  1. LoadLibraryW(  
  2.              LPCSTR lpLibFileName  //DLL文件路徑  
  3.           );  

    

     (2) 定義函數(shù)原型對應(yīng)的函數(shù)指針


     (3)獲取函數(shù)地址

  1. FARPROC  GetProcAddress(//返回對應(yīng)函數(shù)地址  
  2.   
  3.     HMODULE hModule, // DLL句柄  
  4.   
  5.     LPCSTR lpProcName);//函數(shù)名稱  

     注意: a.__declspec(dllexport)導(dǎo)出的函數(shù)由于函數(shù)名稱發(fā)生變化,,所以無法使用函數(shù)名稱獲取對應(yīng)函

                 數(shù)地址,所以盡量采用隱式鏈接的方式,。

            b. extern “C”__declspec(dllexport)方式導(dǎo)出的函數(shù)可以正常使用函數(shù)名稱獲取函數(shù)地址。

            c.使用def導(dǎo)出方式在VC6.0下可使用顯示鏈接(本人在VS2013中對def導(dǎo)出方式導(dǎo)出動態(tài)庫未成功使

              用,,希望哪位大神可以指點迷津)


     (4)使用函數(shù)


     (5)釋放動態(tài)庫

  1. FreeLibrary(HMOUDLE)  

         顯式鏈接示例代碼如下:

  1. #include <iostream>  
  2. #include <Windows.h> /  
  3. #include <tchar.h>  
  4.   
  5. using namespace std;  
  6.   
  7. typedef int(*DLL_ADD)(int nLeft, int nRight);  
  8. typedef int(*DLL_SUB)(int nLeft, int nRight);  
  9. typedef int(*DLL_MUL)(int nLeft, int nRight);  
  10.   
  11. void useDll()  
  12. {  
  13.     HMODULE  hDll = LoadLibrary(_T("Dll_Func.dll"));  
  14.     if (nullptr == hDll)  
  15.     {  
  16.         cout << "Load Failed!" << endl;  
  17.         return;  
  18.     }  
  19.     //定義函數(shù)指針  
  20.     DLL_ADD Dll_Add = nullptr;  
  21.     DLL_SUB Dll_Sub = nullptr;  
  22.     DLL_MUL Dll_Mul = nullptr;  
  23.   
  24.     //獲取函數(shù)地址  
  25.   
  26.     Dll_Add = (DLL_ADD)GetProcAddress(hDll, "Dll_Add");  
  27.     if (nullptr == Dll_Add)  
  28.     {  
  29.         cout << "Get Dll_Add Failed!" << endl;  
  30.     }  
  31.     cout << Dll_Add << endl;  
  32.     Dll_Sub = (DLL_SUB)GetProcAddress(hDll, "Dll_Sub");  
  33.     if (nullptr == Dll_Sub)  
  34.     {  
  35.         cout << "Get Dll_Sub Failed!" << endl;  
  36.     }  
  37.     cout << Dll_Sub << endl;  
  38.     Dll_Mul = (DLL_MUL)GetProcAddress(hDll, "Dll_Mul");  
  39.     if (nullptr == Dll_Mul)  
  40.     {  
  41.         cout << "Get Dll_Mul Failed!" << endl;  
  42.     }  
  43.     cout << Dll_Mul << endl;  
  44.       
  45.     //使用函數(shù)  
  46.     int nSub = Dll_Sub(100, 100);  
  47.     int nAdd = Dll_Add(100, 100);  
  48.     cout << "Add = " << nAdd << endl;  
  49.     cout << "Sub = " << nSub << endl;  
  50.   
  51.   
  52.     //釋放動態(tài)庫  
  53.     FreeLibrary(hDll);  
  54. }  
  55.   
  56. int main()  
  57. {  
  58.     useDll();  
  59.     return 0;  
  60. }  

 

 4.動態(tài)庫中的變量


4.1定義全局變量


4.2導(dǎo)出全局變量


 4.2.1  __declspec(dllexport)導(dǎo)出


 4.2.2 DEF導(dǎo)出

   Int g_nValue1 = 100;

   DEF文件中到處列表增加 g_nValue1 @1 DATA


4.3導(dǎo)入LIB文件


4.4聲明導(dǎo)入變量

 需要使用__declspec(dllimport)聲明變量,,舉例如下:

 extern__declspec(dllimport)int g_nValuel;


4.5使用變量


 動態(tài)庫變量使用代碼示例如下:

  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4. #pragma comment(lib,"../lib/DllValue.lib")  
  5.   
  6. //聲明DLL導(dǎo)入變量  
  7. extern __declspec(dllimport) int g_nValue1;//動態(tài)庫導(dǎo)出文件中有此全局變量,在此再次聲明此變量原型  
  8.   
  9. int main()  
  10. {  
  11.     cout << "g_nValue1 = " << g_nValue1 << endl;  
  12.     return 0;  
  13. }  

 

 5動態(tài)庫的類導(dǎo)出



5.1創(chuàng)建靜態(tài)庫并定義類



5.2導(dǎo)出類


 在類名稱前__declspec(dllexport)定義:


  class__declspec(dllexport)Math


   {……}

 

  導(dǎo)出類示例代碼如下:

  1. //**.h文件  
  2. #ifndef _MATH_H_  
  3. #define _MATH_H_  
  4.   
  5. //定義類導(dǎo)入導(dǎo)出宏,,  
  6. #ifdef _DLLCLASS_DLL__  
  7. #define DLLCLASS_EXT  __declspec(dllexport)  
  8. #else     
  9. #define DLLCLASS_EXT  __declspec(dllimport)  
  10. #endif //_DLLCLASS_DLL_  
  11.   
  12. //增加類的導(dǎo)入 導(dǎo)出符號  
  13. class DLLCLASS_EXT Math  
  14. {  
  15. public:  
  16.   
  17.     Math()  
  18.     {  
  19.     }  
  20.   
  21.     virtual ~Math()  
  22.     {  
  23.     }  
  24.   
  25.     int Add(int nLeft, int nRight);  
  26.     int Sub(int nLeft, int nRight);  
  27. };  
  28.   
  29. #endif  

  1. //**.cpp文件  
  2. #include "Math.h"  
  3.   
  4.   
  5. int Math::Add(int nLeft, int nRight)  
  6. {  
  7.     return (nLeft + nRight);  
  8. }  
  9. int Math::Sub(int nLeft, int nRight)  
  10. {  
  11.     return (nLeft - nRight);  
  12. }  

5.3使用時導(dǎo)入LIB文件


5.4導(dǎo)入類


5.5使用類


5.6關(guān)于類的導(dǎo)入和導(dǎo)出

 5.6.1定義一個宏,,舉例如下(避免多次編寫類頭文件,使之可在導(dǎo)出,、導(dǎo)入時使用同一個頭文件):

     

  1. #ifdef_DLLCLASS_DLL__  
  2.    
  3. #defineDLLCLASS_EXT __declspec(dllexport)  
  4.    
  5. #else    
  6.    
  7. #define DLLCLASS_EXT  __declspec(dllimport)  
  8.    
  9. #endif//_DLLCLASS_DLL_  




 5.6.2 根據(jù)編譯項目修改_DLLCLASS_DLL__宏聲明,,對于導(dǎo)出類,需定義_DLLCLASS_DLL__,,否則,,不需要定義  _DLLCLASS_DLL__,。

 在導(dǎo)出類時,項目設(shè)置如下(即定義_DLLCLASS_DLL__):


 


  6 DllMain函數(shù)(用于變量初始化等操作,。使用可參照3.1.3 (3)中示例代碼)


 Dll文件的入口函數(shù),,當(dāng)程序加載或者釋放動態(tài)庫的時候,會自動調(diào)用此函數(shù)


 BOOL WINAPIDllMain(//返回值代表是否加載成功

     HINSTANCE hinstDll;//DLL句柄

     DWORD  fdwReason;//DLL被調(diào)用的原因

     LPVOID lpvReserved;)//保留值


    FdwReason –

      DLL_PROCESS_ATTACH   進程加載

      DLL_THREAD_ATTACH    線程加載

      DLL_PROCESS_DETACH   進程卸載

      DLL_THREAD_DETACH    線程卸載


   使用導(dǎo)出類代碼示例如下:

 

  1. #include <iostream>  
  2. #include "..\DllClass\Math.h"  
  3. using namespace std;  
  4.   
  5. #pragma comment(lib,"../lib/DllClass.lib")  
  6.   
  7. int main(int argc, char *argv[])  
  8. {  
  9.     Math math;  
  10.     int add = math.Add(100,100);  
  11.     int sub = math.Sub(100,100);  
  12.     cout << "Add = " << add << endl;  
  13.     cout << "Sub = " << sub << endl;  
  14.     return 0;  
  15. }  


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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多