閱讀220 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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文件中。因此如果用的是靜態鏈接庫,那麼也就不存在“導出某個函數提供給用戶使用”的情況,要想用就得全要!要不就都別要!:)

 

 

最後更新:2017-04-03 15:22:11

  上一篇:go SQL中truncate、delete與drop區別
  下一篇:go 網絡子係統29_橋接轉發數據庫