亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

動態link庫編程深入淺出

2024-10-17 09:34:25
3
0
1.概論
  先來闡述一下DLL(Dynamic Linkable Library)的概念,你可以簡單的把DLL看成一種倉庫,它提供給你一些可以直接拿來用的變量、函數或類。在倉庫的發展史上經歷了“無庫-靜態link庫-動態link庫”的時代。
  靜態link庫與動態link庫都是共享代碼的方式,如果采用靜態link庫,則無論你愿不愿意,lib中的指令都被直接包含在最終生成的EXE文件中了。但是若使用DLL,該DLL不必被包含在最終EXE文件中,EXE文件執行時可以“動態”地引用和卸載這個與EXE獨立的DLL文件。靜態鏈接庫和動態鏈接庫的另外一個區別在于靜態鏈接庫中不能再包含其他的動態鏈接庫或者靜態庫,而在動態鏈接庫中還可以再包含其他的動態或靜態鏈接庫。
  對動態link庫,我們還需建立如下概念:
  (1)DLL 的編制與具體的編程語言及編譯器無關
  只要遵循約定的DLL接口規范和調用方式,用各種語言編寫的DLL都可以相互調用。譬如Windows提供的系統DLL(其中包括了Windows的API),在任何開發環境中都能被調用,不在乎其是Visual Basic、Visual C++還是Delphi。
     (2)動態link庫隨處可見
  我們在Windows目錄下的system32文件夾中會看到kernel32.dll、user32.dll和gdi32.dll,windows的大多數API都包含在這些DLL中。kernel32.dll中的函數主要處理內存管理和進程調度;user32.dll中的函數主要控制用戶界面; gdi32.dll中的函數則負責圖形方面的操作。
  一般的程序員都用過類似MessageBox的函數,其實它就包含在user32.dll這個動態link庫中。由此可見DLL對我們來說其實并不陌生。
      (3)VC動態link庫的分類
    Visual C++支持三種DLL,它們分別是Non-MFC DLL(非MFC動態庫)、MFC Regular DLL(MFC規則DLL)、MFC Extension DLL(MFC擴展DLL)。
    非MFC動態庫不采用MFC類庫結構,其導出函數為標準的C接口,能被非MFC或MFC編寫的應用程序所調用;MFC規則DLL 包含一個繼承自CWinApp的類,但其無message循環;MFC擴展DLL采用MFC的動態link版本創建,它只能被用MFC類庫所編寫的應用程序所調用。
動態link庫,導出函數方式:
1、 在函數聲明 中加上__declspec(dllexport);
2、 采用模塊定義(.def) 文件聲明,.def文件為link器提供了有關被link程序的導出、屬性及其他方面的信息
 
下面的代碼演示了怎樣同.def文件將函數add聲明為DLL導出函數(需在dllTest工程中添加lib.def文件):
lib.def : 導出DLL函數
{
    LIBRARY dllTest
    EXPORTS
    add @ 1
}
.def文件的規則為:
  (1)LIBRARY語句說明.def文件相應的DLL;
  (2)EXPORTS語句后列出要導出函數的名稱。可以在.def文件中的導出函數名后加@n,表示要導出函數的序號為n(在進行函數調用時,這個序號將發揮其作用);
  (3).def 文件中的注釋由每個注釋行開始處的分號 (;) 指定,且注釋不能與語句共享一行。
  由此可以看出,例子中lib.def文件的含義為生成名為“dllTest”的動態link庫,導出其中的add函數,并指定add函數的序號為1。
 
DLL的調用方式: “LoadLibrary-GetProcAddress-FreeLibrary”系統Api提供的三位一體“DLL加載-DLL函數adress獲取-DLL釋放”方式,這種調用方式稱為DLL的動態調用
   1、動態調用方式的特點是完全由編程者用 API 函數加載和卸載 DLL,程序員可以決定 DLL 文件何時加載或不加載,顯式link在運行時決定加載哪個 DLL 文件。
   與動態調用方式相對應的就是靜態調用方式,“有動必有靜”,這來源于物質世界的對立統一。“動與靜”,其對立與統一竟無數次在技術領域里得到驗證,譬如 靜態IP與DHCP、靜態路由與動態路由等。從前文我們已經知道,庫也分為靜態庫與動態庫DLL,而想不到,深入到DLL內部,其調用方式也分為靜態與動 態。“動與靜”,無處不在。《周易》已認識到有動必有靜的動靜平衡觀,《易.系辭》曰:“動靜有常,剛柔斷矣”。哲學意味著一種普遍的真理,因此,我們經 常可以在枯燥的技術領域看到哲學的影子。
    2、靜態調用方式的特點是由編譯系統完成對DLL的加載和應用程序結束時 DLL 的卸載。當調用某DLL的應用程序結束時,若系統中還有其它程序使用該 DLL,則Windows對DLL的應用記錄減1,直到所有使用該DLL的程序都結束時才釋放它。靜態調用方式簡單實用,但不如動態調用方式靈活。
  下面我們來看看靜態調用的例子,將編譯dllTest工程所生成的.lib和.dll文件拷入dllCall工程所在的路徑,dllCall執行下列代碼:
#pragma comment(lib,"dllTest.lib")
//.lib文件中僅僅是關于其對應DLL文件中函數的重定位信息
{
     extern "C" __declspec(dllimport) add(int x,int y);
     int main(int argc, char* argv[])
     {
        int result = add(2,3);
        printf("%d",result);
        return 0;
      }
}
  由上述代碼可以看出,靜態調用方式的順利進行需要完成兩個動作:
  (1)告訴編譯器與DLL相對應的.lib文件所在的路徑及文件名,#pragma comment(lib,"dllTest.lib")就是起這個作用。
  程序員在建立一個DLL文件時,連接器會自動為其生成一個對應的.lib文件,該文件包含了DLL 導出函數的符號名及序號(并不含有實際的代碼)。在應用程序里,.lib文件將作為DLL的替代文件參與編譯。
  (2)聲明導入函數,extern "C" __declspec(dllimport) add(int x,int y)語句中的__declspec(dllimport)發揮這個作用。
   靜態調用方式不再需要使用系統API來加載、卸載DLL以及獲取DLL中導出函數的adress。這是因為,當程序員通過靜態link方式編譯生成應用程序時,應用 程序中調用的與.lib文件中導出符號相匹配的函數符號將進入到生成的EXE 文件中,.lib文件中所包含的與之對應的DLL文件的文件名也被編譯器存儲在 EXE文件內部。當應用程序運行過程中需要加載DLL文件時,Windows將根據這些信息發現并加載DLL,然后通過符號名實現對DLL 函數的動態link。這樣,EXE將能直接通過函數名調用DLL的輸出函數,就象調用程序內部的其他函數一樣。
 
__stdcall約定
  如果通過VC++編寫的DLL欲被其他語言編寫的程序調用,應將 函數的調用方式聲明為__stdcall方式,WINAPI都采用這種方式,而C/C++缺省的調用方式卻為__cdecl。__stdcall方式與 __cdecl對函數名最終生成符號的方式不同。若采用C編譯方式(在C++中需將函數聲明為extern "C"),__stdcall調用約定在輸出函數名前面加下劃線,后面加“@”符號和參數的字節數,形如_functionname@number;而 __cdecl調用約定僅在輸出函數名前面加下劃線,形如_functionname。
0條評論
0 / 1000
邱****謀
10文章數
0粉絲數
邱****謀
10 文章 | 0 粉絲
原創

動態link庫編程深入淺出

2024-10-17 09:34:25
3
0
1.概論
  先來闡述一下DLL(Dynamic Linkable Library)的概念,你可以簡單的把DLL看成一種倉庫,它提供給你一些可以直接拿來用的變量、函數或類。在倉庫的發展史上經歷了“無庫-靜態link庫-動態link庫”的時代。
  靜態link庫與動態link庫都是共享代碼的方式,如果采用靜態link庫,則無論你愿不愿意,lib中的指令都被直接包含在最終生成的EXE文件中了。但是若使用DLL,該DLL不必被包含在最終EXE文件中,EXE文件執行時可以“動態”地引用和卸載這個與EXE獨立的DLL文件。靜態鏈接庫和動態鏈接庫的另外一個區別在于靜態鏈接庫中不能再包含其他的動態鏈接庫或者靜態庫,而在動態鏈接庫中還可以再包含其他的動態或靜態鏈接庫。
  對動態link庫,我們還需建立如下概念:
  (1)DLL 的編制與具體的編程語言及編譯器無關
  只要遵循約定的DLL接口規范和調用方式,用各種語言編寫的DLL都可以相互調用。譬如Windows提供的系統DLL(其中包括了Windows的API),在任何開發環境中都能被調用,不在乎其是Visual Basic、Visual C++還是Delphi。
     (2)動態link庫隨處可見
  我們在Windows目錄下的system32文件夾中會看到kernel32.dll、user32.dll和gdi32.dll,windows的大多數API都包含在這些DLL中。kernel32.dll中的函數主要處理內存管理和進程調度;user32.dll中的函數主要控制用戶界面; gdi32.dll中的函數則負責圖形方面的操作。
  一般的程序員都用過類似MessageBox的函數,其實它就包含在user32.dll這個動態link庫中。由此可見DLL對我們來說其實并不陌生。
      (3)VC動態link庫的分類
    Visual C++支持三種DLL,它們分別是Non-MFC DLL(非MFC動態庫)、MFC Regular DLL(MFC規則DLL)、MFC Extension DLL(MFC擴展DLL)。
    非MFC動態庫不采用MFC類庫結構,其導出函數為標準的C接口,能被非MFC或MFC編寫的應用程序所調用;MFC規則DLL 包含一個繼承自CWinApp的類,但其無message循環;MFC擴展DLL采用MFC的動態link版本創建,它只能被用MFC類庫所編寫的應用程序所調用。
動態link庫,導出函數方式:
1、 在函數聲明 中加上__declspec(dllexport);
2、 采用模塊定義(.def) 文件聲明,.def文件為link器提供了有關被link程序的導出、屬性及其他方面的信息
 
下面的代碼演示了怎樣同.def文件將函數add聲明為DLL導出函數(需在dllTest工程中添加lib.def文件):
lib.def : 導出DLL函數
{
    LIBRARY dllTest
    EXPORTS
    add @ 1
}
.def文件的規則為:
  (1)LIBRARY語句說明.def文件相應的DLL;
  (2)EXPORTS語句后列出要導出函數的名稱。可以在.def文件中的導出函數名后加@n,表示要導出函數的序號為n(在進行函數調用時,這個序號將發揮其作用);
  (3).def 文件中的注釋由每個注釋行開始處的分號 (;) 指定,且注釋不能與語句共享一行。
  由此可以看出,例子中lib.def文件的含義為生成名為“dllTest”的動態link庫,導出其中的add函數,并指定add函數的序號為1。
 
DLL的調用方式: “LoadLibrary-GetProcAddress-FreeLibrary”系統Api提供的三位一體“DLL加載-DLL函數adress獲取-DLL釋放”方式,這種調用方式稱為DLL的動態調用
   1、動態調用方式的特點是完全由編程者用 API 函數加載和卸載 DLL,程序員可以決定 DLL 文件何時加載或不加載,顯式link在運行時決定加載哪個 DLL 文件。
   與動態調用方式相對應的就是靜態調用方式,“有動必有靜”,這來源于物質世界的對立統一。“動與靜”,其對立與統一竟無數次在技術領域里得到驗證,譬如 靜態IP與DHCP、靜態路由與動態路由等。從前文我們已經知道,庫也分為靜態庫與動態庫DLL,而想不到,深入到DLL內部,其調用方式也分為靜態與動 態。“動與靜”,無處不在。《周易》已認識到有動必有靜的動靜平衡觀,《易.系辭》曰:“動靜有常,剛柔斷矣”。哲學意味著一種普遍的真理,因此,我們經 常可以在枯燥的技術領域看到哲學的影子。
    2、靜態調用方式的特點是由編譯系統完成對DLL的加載和應用程序結束時 DLL 的卸載。當調用某DLL的應用程序結束時,若系統中還有其它程序使用該 DLL,則Windows對DLL的應用記錄減1,直到所有使用該DLL的程序都結束時才釋放它。靜態調用方式簡單實用,但不如動態調用方式靈活。
  下面我們來看看靜態調用的例子,將編譯dllTest工程所生成的.lib和.dll文件拷入dllCall工程所在的路徑,dllCall執行下列代碼:
#pragma comment(lib,"dllTest.lib")
//.lib文件中僅僅是關于其對應DLL文件中函數的重定位信息
{
     extern "C" __declspec(dllimport) add(int x,int y);
     int main(int argc, char* argv[])
     {
        int result = add(2,3);
        printf("%d",result);
        return 0;
      }
}
  由上述代碼可以看出,靜態調用方式的順利進行需要完成兩個動作:
  (1)告訴編譯器與DLL相對應的.lib文件所在的路徑及文件名,#pragma comment(lib,"dllTest.lib")就是起這個作用。
  程序員在建立一個DLL文件時,連接器會自動為其生成一個對應的.lib文件,該文件包含了DLL 導出函數的符號名及序號(并不含有實際的代碼)。在應用程序里,.lib文件將作為DLL的替代文件參與編譯。
  (2)聲明導入函數,extern "C" __declspec(dllimport) add(int x,int y)語句中的__declspec(dllimport)發揮這個作用。
   靜態調用方式不再需要使用系統API來加載、卸載DLL以及獲取DLL中導出函數的adress。這是因為,當程序員通過靜態link方式編譯生成應用程序時,應用 程序中調用的與.lib文件中導出符號相匹配的函數符號將進入到生成的EXE 文件中,.lib文件中所包含的與之對應的DLL文件的文件名也被編譯器存儲在 EXE文件內部。當應用程序運行過程中需要加載DLL文件時,Windows將根據這些信息發現并加載DLL,然后通過符號名實現對DLL 函數的動態link。這樣,EXE將能直接通過函數名調用DLL的輸出函數,就象調用程序內部的其他函數一樣。
 
__stdcall約定
  如果通過VC++編寫的DLL欲被其他語言編寫的程序調用,應將 函數的調用方式聲明為__stdcall方式,WINAPI都采用這種方式,而C/C++缺省的調用方式卻為__cdecl。__stdcall方式與 __cdecl對函數名最終生成符號的方式不同。若采用C編譯方式(在C++中需將函數聲明為extern "C"),__stdcall調用約定在輸出函數名前面加下劃線,后面加“@”符號和參數的字節數,形如_functionname@number;而 __cdecl調用約定僅在輸出函數名前面加下劃線,形如_functionname。
文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0