• <label id="pxtpz"><meter id="pxtpz"></meter></label>
      1. <span id="pxtpz"><optgroup id="pxtpz"></optgroup></span>

        當(dāng)前位置:雨林木風(fēng)下載站 > 技術(shù)開發(fā)教程 > 詳細(xì)頁面

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

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

        更新時間:2022-05-04 文章作者:未知 信息來源:網(wǎng)絡(luò) 閱讀次數(shù):

        摘要:本文闡述了Windows環(huán)境下動態(tài)鏈接庫的概念和特點,對靜態(tài)調(diào)用和動態(tài)調(diào)用兩種調(diào)用方式作出了比較,并給出了Delphi中應(yīng)用動態(tài)鏈接庫的實例。

          一、動態(tài)鏈接庫的概念

          動態(tài)鏈接庫(Dynamic Link Library,縮寫為DLL)是一個可以被其它應(yīng)用程序共享的程序模塊,其中封裝了一些可以被共享的例程和資源。動態(tài)鏈接庫文件的擴展名一般是dll,也有可能是drv、sys和fon,它和可執(zhí)行文件(exe)非常類似,區(qū)別在于DLL中雖然包含了可執(zhí)行代碼卻不能單獨執(zhí)行,而應(yīng)由Windows應(yīng)用程序直接或間接調(diào)用。

          動態(tài)鏈接是相對于靜態(tài)鏈接而言的。所謂靜態(tài)鏈接是指把要調(diào)用的函數(shù)或者過程鏈接到可執(zhí)行文件中,成為可執(zhí)行文件的一部分。換句話說,函數(shù)和過程的代碼就在程序的exe文件中,該文件包含了運行時所需的全部代碼。當(dāng)多個程序都調(diào)用相同函數(shù)時,內(nèi)存中就會存在這個函數(shù)的多個拷貝,這樣就浪費了寶貴的內(nèi)存資源。而動態(tài)鏈接所調(diào)用的函數(shù)代碼并沒有被拷貝到應(yīng)用程序的可執(zhí)行文件中去,而是僅僅在其中加入了所調(diào)用函數(shù)的描述信息(往往是一些重定位信息)。僅當(dāng)應(yīng)用程序被裝入內(nèi)存開始運行時,在Windows的管理下,才在應(yīng)用程序與相應(yīng)的DLL之間建立鏈接關(guān)系。當(dāng)要執(zhí)行所調(diào)用DLL中的函數(shù)時,根據(jù)鏈接產(chǎn)生的重定位信息,Windows才轉(zhuǎn)去執(zhí)行DLL中相應(yīng)的函數(shù)代碼。

          一般情況下,如果一個應(yīng)用程序使用了動態(tài)鏈接庫,Win32系統(tǒng)保證內(nèi)存中只有DLL的一份復(fù)制品,這是通過內(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應(yīng)用程序共享。

          2. 隱藏實現(xiàn)的細(xì)節(jié)

           DLL中的例程可以被應(yīng)用程序訪問,而應(yīng)用程序并不知道這些例程的細(xì)節(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ù),編譯時在目標(biāo)文件中只保留必要的鏈接信息,而不含DLL函數(shù)的代碼;當(dāng)程序執(zhí)行時,利用鏈接信息加載DLL函數(shù)代碼并在內(nèi)存中將其鏈接入調(diào)用程序的執(zhí)行空間中,其主要目的是便于代碼共享。

          2. Run-time Dynamic Linking

          這種方式是指在編譯之前并不知道將會調(diào)用哪些DLL函數(shù),完全是在運行過程中根據(jù)需要決定應(yīng)調(diào)用哪個函數(shù),并用LoadLibrary和GetProcAddress動態(tài)獲得DLL函數(shù)的入口地址。
        四、DLL的兩種調(diào)用方式在Delphi中的比較

          編寫DLL的目的是為了輸出例程供其他程序調(diào)用,因此在DLL的工程文件中要把輸出的例程用Exports關(guān)鍵字引出。在調(diào)用DLL的應(yīng)用程序中,需要聲明用到的DLL中的方法,聲明格式要和DLL中的聲明一樣。訪問DLL中的例程有靜態(tài)調(diào)用和動態(tài)調(diào)用兩種方式。靜態(tài)調(diào)用方式就是在單元的Interface部分用External指示字列出要從DLL中引入的例程;動態(tài)調(diào)用方式就是通過調(diào)用Windows的API包括LoadLibrary函數(shù)、GetProcAddress函數(shù)以及FreeLibrary函數(shù)動態(tài)的引入DLL中的例程。

          靜態(tài)調(diào)用方式所需的代碼較動態(tài)調(diào)用方式所需的少,但存在著一些不足,一是如果要加載的DLL不存在或者DLL中沒有要引入的例程,這時候程序就自動終止運行;二是DLL一旦加載就一直駐留在應(yīng)用程序的地址空間,即使DLL已不再需要了。動態(tài)調(diào)用方式就可解決以上問題,它在需要用到DLL的時候才通過LoadLibrary函數(shù)引入,用完后通過FreeLibrary函數(shù)從內(nèi)存中卸載,而且通過調(diào)GetProcAddress函數(shù)可以指定不同的例程。最重要的是,如果指定的DLL出錯,至多是API調(diào)用失敗,不會導(dǎo)致程序終止。以下將通過具體的實例說明說明這調(diào)用方式的使用方法。

          1. 靜態(tài)調(diào)用方式

          示例程序創(chuàng)建了一個DLL,其中僅包含一個求兩個整數(shù)的和的函數(shù),在主程序中輸入兩個整數(shù),通過調(diào)用該DLL,即可求出兩個整數(shù)的和,如圖1所示。


        圖1 DLL的靜態(tài)調(diào)用



          該DLL的程序代碼如下:

        library AddNum;
        uses
        SysUtils,
        Classes;

        {$R *.res}

        function AddNumber(Num1,Num2:integer):integer;stdcall; //定義求和函數(shù)
         begin
          result:=Num1+Num2;
         end;
          exports
          AddNumber; //引出求和函數(shù)
         begin
        end.

          主程序在調(diào)用該DLL時,首先在interface部分聲明要調(diào)用的函數(shù):

        function AddNum(Num1,Num2:integer):integer;stdcall;external 'AddNum.dll'
        name 'AddNumber';

          然后在按鈕控件的事件中寫入如下代碼:

        procedure TForm1.Button1Click(Sender: TObject);
        var
         Number1,Number2:integer;
         Sum:integer;
        begin
         Number1:=strtoint(Edit1.Text);
         Number2:=strtoint(Edit2.Text);
         Sum:=AddNum(Number1,Number2); //調(diào)用求和函數(shù)計算結(jié)果
         Edit3.Text:=inttostr(Sum);
        end;
        2.動態(tài)調(diào)用方式

          這個示例程序創(chuàng)建了一個顯示日期的DLL,其中包含一個窗體,如圖2所示。


        圖2 DLL的動態(tài)調(diào)用



          程序中定義了一個ShowCalendar函數(shù),返回在這個窗體中設(shè)定的日期。函數(shù)定義如下:

        function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime;
        var
         DLLForm: TDLLForm;
        begin
         Application.Handle := AHandle;
         DLLForm := TDLLForm.Create(Application); //創(chuàng)建并顯示窗體
         try
          DLLForm.Caption := ACaption;
          DLLForm.ShowModal; //顯示方式為模式化
          Result := DLLForm.calDLLCalendar.CalendarDate; //返回設(shè)定日期
         finally
          DLLForm.Free; //用完后卸載該窗體
         end;
        end;

          在DLL的工程文件中用exports ShowCalendar; 語句引出該函數(shù)。下面通過一個簡單的應(yīng)用程序測試一下該DLL文件。新建一個工程文件,在窗體中放置一個Label控件和一個按鈕控件,在按鈕控件的OnClick事件中編寫如下代碼:

        procedure TMainForm.Button1Click(Sender: TObject);
        var
         OneHandle : THandle; //定義一個句柄變量
        begin
         OneHandle := LoadLibrary('Clendar.dll'); //動態(tài)載入DLL,并返回其句柄
         try
          if OneHandle <> 0 then //如果載入成功則獲取ShowCalendar函數(shù)的地址
           @ShowCalendar := GetProcAddress(OneHandle, 'ShowCalendar');
           if not (@ShowCalendar = nil) then
            //如果找到該函數(shù)則在主窗體的Label1中顯示DLL窗體中設(shè)定的日期
            Label1.Caption := DateToStr(ShowCalendar(Application.Handle, Caption))
           else
            RaiseLastWin32Error;
         finally
          FreeLibrary(OneHandle); //調(diào)用完畢收回DLL占用的資源
         end;
        end;

          從以上程序中可以看到DLL的動態(tài)調(diào)用方式比靜態(tài)調(diào)用方式的優(yōu)越之處。DLL例程在用到時才被調(diào)入,用完后就被卸載,大大減少了系統(tǒng)資源的占用。在調(diào)用LoadLibrary函數(shù)時可以明確指定DLL的完整路徑,如果沒有指定路徑,運行時首先查找應(yīng)用程序載入的目錄,然后是Windows系統(tǒng)的System目錄和環(huán)境變量Path設(shè)定的路徑。

          五、結(jié)束語

          由于動態(tài)鏈接庫可以實現(xiàn)代碼和資源的共享,大大減少系統(tǒng)資源的占用,因此在當(dāng)今的應(yīng)用程序開發(fā)中起著非常重要的作用。Delphi是現(xiàn)今流行的應(yīng)用軟件開發(fā)工具,本文就如何在Delphi中使用動態(tài)鏈接庫給出了一定程度上的闡述。

        溫馨提示:喜歡本站的話,請收藏一下本站!

        本類教程下載

        系統(tǒng)下載排行

        主站蜘蛛池模板: 亚洲男人天堂2020| 男人的天堂亚洲一区二区三区 | 亚洲AV无码乱码在线观看裸奔| 国产成人精品亚洲| 免费看国产一级片| 丁香花在线观看免费观看图片| 国产精品酒店视频免费看| 亚洲一区二区三区成人网站| 免费无码肉片在线观看| 亚洲精品国产精品国自产网站| 希望影院高清免费观看视频| 色在线亚洲视频www| 免费黄色app网站| 疯狂做受xxxx高潮视频免费| 亚洲日本va午夜中文字幕久久| 乱淫片免费影院观看| 国产亚洲精品久久久久秋霞| 最新国产乱人伦偷精品免费网站 | 一级A毛片免费观看久久精品 | 免费一看一级毛片| xxxxx做受大片视频免费| 一本色道久久综合亚洲精品高清| 丝瓜app免费下载网址进入ios| 亚洲国产成人久久精品影视| 美女被cao免费看在线看网站| 亚洲精品动漫免费二区| 亚洲美女高清一区二区三区| 国产精品免费观看调教网| 亚洲午夜国产精品无卡| 国产又黄又爽又猛的免费视频播放| xvideos永久免费入口| 亚洲综合色一区二区三区小说| 在线中文高清资源免费观看| 一本久久A久久免费精品不卡| 亚洲免费在线视频| 日韩高清免费观看| 成在人线av无码免费高潮喷水 | 久久国产亚洲高清观看| 无码国产精品一区二区免费模式 | 久久精品a亚洲国产v高清不卡| 毛片大全免费观看|