Delphi中動態(tài)鏈接庫兩種調(diào)用方式的比較

字號:

一、動態(tài)鏈接庫的概念
    動態(tài)鏈接庫(Dynamic Link Library,縮寫為DLL)是一個可以被其它應用程序共享的程序模塊,其中封裝了一些可以被共享的例程和資源。動態(tài)鏈接庫文件的擴展名一般是dll,也有可能是drv、sys和fon,它和可執(zhí)行文件(exe)非常類似,區(qū)別在于DLL中雖然包含了可執(zhí)行代碼卻不能單獨執(zhí)行,而應由Windows應用程序直接或間接調(diào)用。
    動態(tài)鏈接是相對于靜態(tài)鏈接而言的。所謂靜態(tài)鏈接是指把要調(diào)用的函數(shù)或者過程鏈接到可執(zhí)行文件中,成為可執(zhí)行文件的一部分。換句話說,函數(shù)和過程的代碼就在程序的exe文件中,該文件包含了運行時所需的全部代碼。當多個程序都調(diào)用相同函數(shù)時,內(nèi)存中就會存在這個函數(shù)的多個拷貝,這樣就浪費了寶貴的內(nèi)存資源。而動態(tài)鏈接所調(diào)用的函數(shù)代碼并沒有被拷貝到應用程序的可執(zhí)行文件中去,而是僅僅在其中加入了所調(diào)用函數(shù)的描述信息(往往是一些重定位信息)。僅當應用程序被裝入內(nèi)存開始運行時,在Windows的管理下,才在應用程序與相應的DLL之間建立鏈接關(guān)系。當要執(zhí)行所調(diào)用DLL中的函數(shù)時,根據(jù)鏈接產(chǎn)生的重定位信息,Windows才轉(zhuǎn)去執(zhí)行DLL中相應的函數(shù)代碼。
    一般情況下,如果一個應用程序使用了動態(tài)鏈接庫,Win32系統(tǒng)保證內(nèi)存中只有DLL的一份復制品,這是通過內(nèi)存映射文件實現(xiàn)的。DLL首先被調(diào)入Win32系統(tǒng)的全局堆棧,然后映射到調(diào)用這個DLL的進程地址空間。在Win32系統(tǒng)中,每個進程擁有自己的32位線性地址空間,如果一個DLL被多個進程調(diào)用,每個進程都會收到該DLL的一份映像。與16位Windows不同,在Win32中DLL可以看作是每個進程自己的代碼。
    二、動態(tài)鏈接庫的優(yōu)點
    1. 共享代碼、資源和數(shù)據(jù)
    使用DLL的主要目的就是為了共享代碼,DLL的代碼可以被所有的Windows應用程序共享。
    2. 隱藏實現(xiàn)的細節(jié)
    DLL中的例程可以被應用程序訪問,而應用程序并不知道這些例程的細節(jié)。
    3. 拓展開發(fā)工具如Delphi的功能
    由于DLL是與語言無關(guān)的,因此可以創(chuàng)建一個DLL,被C++、VB或任何支持動態(tài)鏈接庫的語言調(diào)用。這樣如果一種語言存在不足,就可以通過訪問另一種語言創(chuàng)建的DLL來彌補。
    三、動態(tài)鏈接庫的實現(xiàn)方法
    1. Load-time Dynamic Linking
    這種用法的前提是在編譯之前已經(jīng)明確知道要調(diào)用DLL中的哪幾個函數(shù),編譯時在目標文件中只保留必要的鏈接信息,而不含DLL函數(shù)的代碼;當程序執(zhí)行時,利用鏈接信息加載DLL函數(shù)代碼并在內(nèi)存中將其鏈接入調(diào)用程序的執(zhí)行空間中,其主要目的是便于代碼共享。
    2. Run-time Dynamic Linking
    這種方式是指在編譯之前并不知道將會調(diào)用哪些DLL函數(shù),完全是在運行過程中根據(jù)需要決定應調(diào)用哪個函數(shù),并用LoadLibrary和GetProcAddress動態(tài)獲得DLL函數(shù)的入口地址。