2014百度校招筆試題之動態鏈接庫&靜態鏈接庫詳解
1.什麼是靜態連接庫,什麼是動態鏈接庫
靜態鏈接庫用通俗的話講,靜態庫就是將代碼編譯到一個二進制文件下(通常擴展名為.LIB).然後客戶端調用程序,只需要包含相關的.h文件及LIB庫文件一起鏈接到exe文件中.可執行程序發布後,不再需要該.lib文件了.
動態鏈接庫最終將編譯出.lib與.dll文件. 注意.lib文件與上面的靜態庫雖然擴展名相同,但有本質的區別.動態庫中的lib文件是動態庫的引入庫. 該引入庫包含被DLL導出的函數和變量的"符號 名".而靜態庫中的.lib包含了函數和數據,動態庫的函數和數據是編譯到.dll中.動態鏈接庫調用方式分為隱式調用與顯示調用(也稱靜態調用與動態調用)。
2.動態鏈接庫與靜態鏈接庫的使用時機
2.1用動態庫的時機:
1)大系統,開發組多.減輕Build的負擔。
2)不同語言版本的資源。數據/代碼分離。
3)模塊可以適應很多程序使用,而且程序可能安裝到同一個系統中。比如IE 與 Outlook 會共用很多Dll.
1) 2)是工程管理的需要,3)是節省空間的需要。
但是Dll也會造成浪費,每個Dll的基本代碼(例如內存管理等C runtime)是相同的。所以如果庫比較小,還是使用LIB比較好。
動態庫的應用有兩個主要原因:
1、共享。多個程序可以使用同一個動態庫
2、開發模式好。要求設計者對功能劃分得更好
但動態庫裝載的時候慢,特別是運行中裝載有明顯延遲。一旦裝載完畢執行起來根靜態庫比較慢不了。
2.2靜態庫的優點:
代碼裝載速度快,執行速度略比動態庫快。
3.動態鏈接庫和靜態鏈接庫的使用
3.1對於動態鏈接庫:
動態鏈接庫的使用,根據不同的調用方法,需要提供不同的資源:
1. 靜態加載------程序靜態編譯的時候就靜態導入dll,這樣的話就需要提供給庫使用者(C客戶)如下文件:*.lib文件和.dll文件和*.h。其有2個壞處:
1 程序一開始運行就需要載入整個dll,無法載入程序就不能開始運行;
2 由於載入的是整個dll,需要耗費資源較多
其調用方法如下:
#include"..\lib.h"
#pragma comment(lib,"..\\debug\\libTest.lib")
但是這種方式的話可以調用Classmethod.
2.動態加載-----那麼只需要提供dll文件。
因此調用程序若想調用DLL中的某個函數就要以某種形式或方式指明它到底想調用哪一個函數。但是無法調用Classmethod了。
如果要調用Dll中的function,需要經歷3個步驟:
Handle h=LoadLibrary(dllName) --> GetProcAddress(h,functionName) 返回函數指針,通過函指針調用其function-->FreeLibrary(h)
例如:Another.dll有一個intAdd(int x,int y)函數。則完整的調用過程如下:
typedef int (* FunPtr)(int,int);//定義函數指針
FunPtr funPtr;
Handle h=LoadLibrary("Another.dll");
funPtr=(FunPtr)GetProcAddress(h,"Add");
funPtr(2,3);//2+3;
FreeLibrary(h);
3.2對於靜態鏈接庫:
首先,靜態鏈接庫的使用需要庫的開發者提供生成庫的.h頭文件和.lib文件。
生成庫的.h頭文件中的聲明格式如下:
extern "C" 函數返回類型 函數名(參數表);
在調用程序的.cpp源代碼文件中如下:
#include"..\lib.h"
#pragmacomment(lib,"..\\debug\\libTest.lib")
//指定與靜態庫一起鏈接
第二,因為靜態鏈接庫是將全部指令都包含入調用程序生成的EXE文件中。因此如果用的是靜態鏈接庫,那麼也就不存在“導出某個函數提供給用戶使用”的情況,要想用就得全要!要不就都別要!:)