Use static libary, static linked DLL, dynamic linked DLL 概念

節選自:http://topic.csdn.net/t/20010103/10/54462.html

 

在真實世界中,有三個概念:Use static libary, static linked DLL, dynamic linked DLL.
多數人混淆了static libary 和 static linked DLL的概念,當然他們有似是而非的"相似之處",比如都用到.lib,下面具體說明。
使用靜態庫(Use static libary)是把.lib和其他.obj一起build在目標文件中,目標文件可以是.exe,也可以是.dll或.oxc等。一般情況下,可以根本就沒有"對應的".dll 文件,如C Run Time(CRT)庫。一個例子就是,寫一個main(){},build出來並不是只有幾個字節,當然有人會說那還有exe文件頭呢?是,即使加上文件頭的尺寸,build出的執行文件仍然"莫名的大"。實際上那多出來的部分就是CRT靜態庫。姑且可以把靜態庫.lib理解成外部程序的obj文件比較合理,它包含了函數的實現。


下面再談static linked DLL 和 dynamic linked DLL又如何?
靜態鏈接 (static linked DLL)從操作上在VC的Project|Settings...|Link (tab)|General (category)|Object/library modules 中設置和添加。比如要使用SDK中的PropertySheet() API, 就要在這裏添加 comctl32.lib,然後再調用的源程序中#include <prsht.h> , 使用的地方直接調用PropertySheet()。當程序.exe啓動時,系統會把對應comctl32.dll加載進來。作爲DLL的靜態引入庫的.lib不包含函數的實現,只包含用於系統加載的信息,如對應的DLL名稱,函數歧視地只在對應的DLL中的便宜等等。相比動態鏈接而言,靜態鏈接是很簡單的。
動態鏈接是使用LoadLibrary()/GetProcessAddress()和FreeLibrary(),詳見下面的例子。

{
typedef BOOL (WINAPI *LPFNSHELLEXECUTEEX)(LPSHELLEXECUTEINFO);

hShell32Dll = LoadLibrary(TEXT( "SHELL32.DLL "));
if (!hShell32Dll) { goto End; }

lpfnShellExecuteEx = (LPFNSHELLEXECUTEEX)GetProcAddress(hShell32Dll,
API_NAME(ShellExecuteEx));
if (!lpfnShellExecuteEx) { goto End; }

...
fOk = (*lpfnShellExecuteEx)(pShellExecuteInfo);
...
End:
if (hShell32Dll) {
FreeLibrary(hShell32Dll);
}
lpfnShellExecuteEx = NULL;
...
}
有人會想,動態鏈接這樣麻煩,爲什麼還要用呢?這裏有一個技術問題,對這個問題的解決直接導致了動態加載的需求。問題是有些DLL只在某個Windows版本中存在,或某個API只在某些Windows版本中被加入指定的DLL。當你使用靜態鏈接的.exe試圖在不支持的Windows版本上運行時,系統會彈出系統對話框提示某某.dll無法加載或無法定位某某API的消息,然後就中止.exe的運行。像這樣因爲個別功能的實現依賴於某個DLL,當這個DLL不可用時導致整個.exe無法運行是不明智的。避免這樣的結局只有用動態鏈接。

 

發佈了41 篇原創文章 · 獲贊 2 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章