摘要:本文闡述了 windows 環境下動態鏈結庫的概念和特點,對靜態呼叫和動態呼叫兩種呼叫方式作出了比較,並給出了 delphi 中應用動態鏈結庫的例項。
一、動態鏈結庫的概念
動態鏈結庫( dynamic link library ,縮寫為 dll )是乙個可以被其它應用程式共享的程式模組,其中封裝了一些可以被共享的例程和資源。動態鏈結庫檔案的副檔名一般是 dll , 也有可能是 drv 、 sys 和 fon ,它和可執行檔案( exe )非常類似,區別在於 dll 中雖然包含了可執行**卻不能單獨執行,而應由 windows 應用 程式直接或間接呼叫。
動態鏈結是相對於靜態鏈結而言的。所謂靜態鏈結是指把要呼叫的函式或者過程鏈結到可執行檔案中,成為可執行檔案 的一部分。換句話說,函式和過程的**就在程式的 exe 檔案中,該檔案包含了執行時所需的全部**。當多個程式都呼叫相同函式時,記憶體中就會存在這個函式 的多個拷貝,這樣就浪費了寶貴的記憶體資源。而動態鏈結所呼叫的函式**並沒有被拷貝到應用程式的可執行檔案中去,而是僅僅在其中加入了所呼叫函式的描述信 息(往往是一些重定位資訊)。僅當應用程式被裝入記憶體開始執行時,在 windows 的管理下,才在應用程式與相應的 dll 之間建立鏈結關係。當要執行所調 用 dll 中的函式時,根據鏈結產生的重定位資訊, windows 才轉去執行 dll 中相應的函式**。
一般情況下,如果乙個應用程式使 用了動態鏈結庫, win32 系統保證記憶體中只有 dll 的乙份複製品,這是通過記憶體對映檔案實現的。 dll 首先被調入 win32 系統的全域性堆疊,然後對映到 呼叫這個 dll 的程序位址空間。在 win32 系統中,每個程序擁有自己的 32 位線性位址空間,如果乙個 dll 被多個程序呼叫,每個程序都會收到該 dll 的 乙份映像。與 16 位 windows 不同,在 win32 中 dll 可以看作是每個程序自己的**。
二、動態鏈結庫的優點
1 . 共享**、資源和資料
使用 dll 的主要目的就是為了共享**, dll 的**可以被所有的 windows 應用程式共享。
2 . 隱藏實現的細節
dll 中的例程可以被應用程式訪問,而應用程式並不知道這些例程的細節。
3 . 拓展開發工具如 delphi 的功能
由於 dll 是與語言無關的,因此可以建立乙個 dll ,被 c++ 、 vb 或任何支援動態鏈結庫的語言呼叫。這樣如果一種語言存在不足,就可以通過訪問另一種語言建立的 dll 來彌補。
三、動態鏈結庫的實現方法
1 . load-time dynamic linking
這種用法的前提是在編譯之前已經明確知道要呼叫 dll 中的哪幾個函式,編譯時在目標檔案中只保留必要的鏈結資訊,而不含 dll 函式的**;當程式執行時,利用鏈結資訊載入 dll 函式**並在記憶體中將其鏈結入呼叫程式的執行空間中,其主要目的是便於**共享。
2 . run-time dynamic linking
這種方式是指在編譯之前並不知道將會呼叫哪些 dll 函式,完全是在執行過程中根據需要決定應呼叫哪個函式,並用 loadlibrary 和 getprocaddress 動態獲得 dll 函式的入口位址。
四、dll 的兩種呼叫方式在delphi 中的比較
編寫dll 的目的是為了輸出例程供其他程式呼叫,因此在dll 的工程檔案中要把輸出的例程用exports 關鍵字引出。在呼叫dll 的應用程式中,需要 宣告用到的dll 中的方法,宣告格式要和dll 中的宣告一樣。訪問dll 中的例程有靜態呼叫和動態呼叫兩種方式。靜態呼叫方式就是在單元的 inte***ce 部分用external 指示字列出要從dll 中引入的例程;動態呼叫方式就是通過呼叫windows 的api 包括 loadlibrary 函式、getprocaddress 函式以及freelibrary 函式動態的引入dll 中的例程。
靜態呼叫 方式所需的**較動態呼叫方式所需的少,但存在著一些不足,一是如果要載入的dll 不存在或者dll 中沒有要引入的例程,這時候程式就自動終止執行;二是 dll 一旦載入就一直駐留在應用程式的位址空間,即使dll 已不再需要了。動態呼叫方式就可解決以上問題,它在需要用到dll 的時候才通過 loadlibrary 函式引入,用完後通過freelibrary 函式從記憶體中解除安裝,而且通過調getprocaddress 函式可以指定不同的例程。 最重要的是,如果指定的dll 出錯,至多是api 呼叫失敗,不會導致程式終止。以下將通過具體的例項說明說明這呼叫方式的使用方法。
1 . 靜態呼叫方式
示例程式建立了乙個dll ,其中僅包含乙個求兩個整數的和的函式,在主程式中輸入兩個整數,通過呼叫該dll ,即可求出兩個整數的和,如圖1 所示。
該dll 的程式**如下:
library addnum;
uses
sysutils,
classes;
function addnumber(num1,num2:integer):integer;stdcall; // 定義求和函式
begin
result:=num1+num2;
end;
exports
addnumber; // 引出求和函式
begin
end.
主程式在呼叫該dll 時,首先在inte***ce 部分宣告要呼叫的函式:
function addnum(num1,num2:integer):integer;stdcall;external 'addnum.dll'
name 'addnumber';
然後在按鈕控制項的事件中寫入如下**:
procedure tform1.button1click(sender: tobject);
varnumber1,number2:integer;
sum:integer;
begin
number1:=strtoint(edit1.text);
number2:=strtoint(edit2.text);
sum:=addnum(number1,number2); // 呼叫求和函式計算結果
edit3.text:=inttostr(sum);
end;
2 .動態呼叫方式
這個示例程式建立了乙個顯示日期的dll ,其中包含乙個窗體,如圖2 所示。
程式中定義了乙個showcalendar 函式,返回在這個窗體中設定的日期。函式定義如下:
在dll 的工程檔案中用exports showcalendar; 語句引出該函式。下面通過乙個簡單的應用程式測試一下該dll 檔案。新建乙個工程檔案,在窗體中放置乙個label 控制項和乙個按鈕控制項,在按鈕控制項的onclick 事件中編寫如下**:
從以上程式中可以看到dll 的動態呼叫方式比靜態呼叫方式的優越之處。dll 例程在用到時才被調入,用完後就被解除安裝,大大減少了系統資源的占用。在呼叫 loadlibrary 函式時可以明確指定dll 的完整路徑,如果沒有指定路徑,執行時首先查詢應用程式載入的目錄,然後是windows 系統的 system 目錄和環境變數path 設定的路徑。
五、結束語
由於動態鏈結庫可以實現**和資源的共享,大大減少系統資源的占用,因此在當今的應用程式開發中起著非常重要的作用。delphi 是現今流行的應用軟體開發工具,本文就如何在delphi 中使用動態鏈結庫給出了一定程度上的闡述。
php 靜態呼叫與動態呼叫
當用 使用方法是被認為該方法為靜態方法,靜態方法中不允許使用 this,因為靜態方法的呼叫不需要例項化,而 this是例項化後才出現的,所以靜態方法類似於乙個普通的函式 靜態方法是加栽到記憶體.而且還少了 new 的記憶體空間.速度相對快一點效率好點tukiz29 例 class a else cl...
DELPHI中動態呼叫dll
顯式例子 unit main inte ce uses windows,messages,sysutils,variants,classes,graphics,controls,forms,dialogs,stdctrls,extctrls,grids,dbgrids,db,dbtables,dbc...
delphi動態呼叫dll窗體
宣告 tshowform function ahandle thandle acaption pchar boolean stdcall 呼叫 procedure tform1.n5click sender tobject var mainfrm,dllform thandle showform t...