程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 寫你的dll文件(2)

寫你的dll文件(2)

編輯:Delphi

在Delphi中靜態調用DLL top

   調用一個DLL比寫一個DLL要容易一些。首先給大家介紹的是靜態調用方法,稍後將介紹動態調用方法,並就兩種方法做一個比較。同樣的,我們先舉一個靜態調用的例子。

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

//本行以下代碼為我們真正動手寫的代碼

function TestDll(i:integer):integer;stdcall;
external ’Delphi.dll’;

procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text:=IntToStr(TestDll(1));
end;

end.

   上面的例子中我們在窗體上放置了一個編輯框(Edit)和一個按鈕(Button),並且書寫了很少的代碼來測試我們剛剛編寫的Delphi.dll。大家可以看到我們唯一做的工作是將TestDll函數的說明部分放在了implementation中,並且用external語句指定了Delphi.dll的位置。(本例中調用程序和Delphi.dll在同一個目錄中。)讓人興奮的是,我們自己編寫的TestDll函數很快被Delphi認出來了。您可做這樣一個實驗:輸入“TestDll(”,很快Delphi就會用fly-by提示條提示您應該輸入的參數是什麼,就像我們使用Delphi中定義的其他函數一樣簡單。注意事項有以下一些:

一、調用參數用stdcall

   和前面提到的一樣,當引用DLL中的函數和過程時也要使用stdcall參數,原因和前面提到的一樣。

二、用external語句指定被調用的DLL文件的路徑和名稱

   正如大家看到的,我們在external語句中指定了所要調用的DLL文件的名稱。沒有寫路徑是因為該DLL文件和調用它的主程序在同一目錄下。如果該DLL文件在C:,則我們可將上面的引用語句寫為external ’C:Delphi.dll’。注意文件的後綴.dll必須寫上。

三、不能從DLL中調用全局變量

   如果我們在DLL中聲明了某種全局變量,如:var s:byte 。這樣在DLL中s這個全局變量是可以正常使用的,但s不能被調用程序使用,既s不能作為全局變量傳遞給調用程序。不過在調用程序中聲明的變量可以作為參數傳遞給DLL。

四、被調用的DLL必須存在

   這一點很重要,使用靜態調用方法時要求所調用的DLL文件以及要調用的函數或過程等等必須存在。如果不存在或指定的路徑和文件名不正確的話,運行主程序時系統會提示“啟動程序時出錯”或“找不到*.dll文件”等運行錯誤。

在Delphi中動態調用DLL top

   動態調用DLL相對復雜很多,但非常靈活。為了全面的說明該問題,這次我們舉一個調用由C++編寫的DLL的例子。首先在C++中編譯下面的DLL源程序。

#include

extern ”C” _declspec(dllexport)
int WINAPI TestC(int i)
{
return i;
}
   編譯後生成一個DLL文件,在這裡我們稱該文件為Cpp.dll,該DLL中只有一個返回整數類型的函數TestC。為了方便說明,我們仍然引用上面的調用程序,只是將原來的Button1Click過程中的語句用下面的代碼替換掉了。


procedure TForm1.Button1Click(Sender: TObject);
type
TIntFunc=function(i:integer):integer;stdcall;
var
Th:Thandle;
Tf:TIntFunc;
Tp:TFarProc;
begin
Th:=LoadLibrary(’Cpp.dll’); {裝載DLL}
if Th>0 then
try
Tp:=GetProcAddress(Th,PChar(’TestC’));
if Tp<>nil
then begin
Tf:=TIntFunc(Tp);
Edit1.Text:=IntToStr(Tf(1)); {調用TestC函數}
end
else
ShowMessage(’TestC函數沒有找到’);
finally
FreeLibrary(Th); {釋放DLL}
end
else
ShowMessage(’Cpp.dll沒有找到’);
end;

   大家已經看到了,這種動態調用技術很復雜,但只要修改參數,如修改LoadLibrary(’Cpp.dll’)中的DLL名稱為’Delphi.dll’就可動態更改所調用的DLL。

一、定義所要調用的函數或過程的類型

   在上面的代碼中我們定義了一個TIntFunc類型,這是對應我們將要調用的函數TestC的。在其他調用情況下也要做同樣的定義工作。並且也要加上stdcall調用參數。

二、釋放所調用的DLL

   我們用LoadLibrary動態的調用了一個DLL,但要記住必須在使用完後手動地用FreeLibrary將該DLL釋放掉,否則該DLL將一直占用內存直到您退出Windows或關機為止。

   現在我們來評價一下兩種調用DLL的方法的優缺點。靜態方法實現簡單,易於掌握並且一般來說稍微快一點,也更加安全可靠一些;但是靜態方法不能靈活地在運行時裝卸所需的DLL,而是在主程序開始運行時就裝載指定的DLL直到程序結束時才釋放該DLL,另外只有基於編譯器和鏈接器的系統(如Delphi)才可以使用該方法。動態方法較好地解決了

[1] [2] 下一頁

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved