在Delphi和VC中建立和調用動態連結程式庫

來源:互聯網
上載者:User

大家在軟體開發時經常會遇到這樣的情況,在不同的開發環境中為實現一些功能相同的過程,由於開發所使用的設計語言不同,因而不得不編寫許多類似的代碼,甚至有時要在同一個開發環境不同項目中重寫代碼,這就造成了很大的資源浪費。動態連結程式庫能較好的解決這個問題,重複利用代碼將大大提高了開發效率。一般,使用者在應用程式中基於如下要求建立和使用DLL:

  1. 在不同的可執行檔之間共用的程式;

  2. 在設計應用程式時,將其拆分成各個相互獨立功能組件,為以後這些功能組件各自升級提供方便的途徑。

  動態連結程式庫將共用程式或功能組件做成庫中的函數,形成DLL檔案,其它應用程式通過使用DLL調用這些函數。在這裡將對Delphi和VC中建立和使用動態連結程式庫的方法做一介紹。Delphi和VC定義的動態連結程式庫均可在兩者的開發環境中使用。

  一、 用Delphi建立DLL

  Delphi的DLL建立並不複雜,下面向大家介紹Delphi的DLL建立方法。

  (1)首先建立一個新的DLL項目(NewProject)project1,檔案頭部為:

library Project1;

  (2)USES語句後面加入ExPorts語句,指明調用DLL的函數名,形式為:

exports
checkpwd name 'checkpwd';

  (3)在DLL的Pas檔案中Type......End後加入該DLL的函數或過程的聲明,形式如下:

FunctionName(argment):Boolean;export;

  
  該函數也可以存在於另一個pas檔案中(如Unit1.pas),此時只需在專案檔中加入:

uses
Unit1 in 'Unit1.pas' {Form1};

  值得注意的是,該函數或過程應加入表單的Create和Free(產生和釋放)方法。

  (4)對項目進行編譯即形成DLL檔案,可被其它項目調用。

二、Delphi中DLL的調用

  調用DLL有兩種方法,一種是在應用程式裝載時調用,另一種是在應用程式運行時調用。

  (1) 裝載時調用DLL

  在調用DLL的Pas檔案中,對DLL函數進行外部聲明,聲明應位於Implementation後,形式如下:

Implementation
Function functionname(argment):Boolean;far;External 'DllName';

  
  其中External關鍵字後面的引號內是DLL的檔案名稱,該檔案一般應放在系統的system目錄下,或與調用它的項目同一目錄。聲明以後即可在Pas檔案任何地方引用DLL函數。

  裝載時調用DLL的優點是速度較快,程式間也可共用代碼。

  (2) 運行時調用DLL

  DLL的另一種調用方法是在運行時調用。這種方法要調用到Windows的API函數LoadLibrary,GetProcAddress,FreeLibrary等。此方法主要用於調用其它語言,特別是C++編譯的DLL。

  假定你欲調用的DLL中包括一個函數:

Function checkpwd(pwd:string):boolean;export;

  
  那麼,首先在欲調用DLL的程式Type型別宣告處加入一句:

Type
Tcheckpwd= function(pwd:string):boolean;

  
  此句的作用如同C++中聲明的函數指標。

  然後定義如下變數∶

Var
  aptr:TFarproc;
lhnd:THandle;
flag:boolean;

  其中Aptr,lhnd兩變數聲明必須有,flag是DLL函數傳回值,視情況而定。在調用DLL處加入如下語句進行DLL裝載:

lhnd:=Loadlibrary('路徑:DLL檔案名稱');{如lhnd:=Loadlibrary('c:/project1.dll');
aptr:=GetprocAddress(lhnd,'checkpwd');

  
  下面可直接調用DLL了:

flag:=Tcheckpwd(aptr)( 'pwd');{根據函數填相應的變數參數}

  
  調用完以後,用FreeLibrary釋放DLL佔用的記憶體:

FreeLibrary(lhnd);

二、Delphi中DLL的調用

  調用DLL有兩種方法,一種是在應用程式裝載時調用,另一種是在應用程式運行時調用。

  (1) 裝載時調用DLL

  在調用DLL的Pas檔案中,對DLL函數進行外部聲明,聲明應位於Implementation後,形式如下:

Implementation
Function functionname(argment):Boolean;far;External 'DllName';

  
  其中External關鍵字後面的引號內是DLL的檔案名稱,該檔案一般應放在系統的system目錄下,或與調用它的項目同一目錄。聲明以後即可在Pas檔案任何地方引用DLL函數。

  裝載時調用DLL的優點是速度較快,程式間也可共用代碼。

  (2) 運行時調用DLL

  DLL的另一種調用方法是在運行時調用。這種方法要調用到Windows的API函數LoadLibrary,GetProcAddress,FreeLibrary等。此方法主要用於調用其它語言,特別是C++編譯的DLL。

  假定你欲調用的DLL中包括一個函數:

Function checkpwd(pwd:string):boolean;export;

  
  那麼,首先在欲調用DLL的程式Type型別宣告處加入一句:

Type
Tcheckpwd= function(pwd:string):boolean;

  
  此句的作用如同C++中聲明的函數指標。

  然後定義如下變數∶

Var
  aptr:TFarproc;
lhnd:THandle;
flag:boolean;

  其中Aptr,lhnd兩變數聲明必須有,flag是DLL函數傳回值,視情況而定。在調用DLL處加入如下語句進行DLL裝載:

lhnd:=Loadlibrary('路徑:DLL檔案名稱');{如lhnd:=Loadlibrary('c:/project1.dll');
aptr:=GetprocAddress(lhnd,'checkpwd');

  
  下面可直接調用DLL了:

flag:=Tcheckpwd(aptr)( 'pwd');{根據函數填相應的變數參數}

  
  調用完以後,用FreeLibrary釋放DLL佔用的記憶體:

FreeLibrary(lhnd);

三、用VC建立DLL

  在VC中建立DLL,與Delphi中的建立過程相似,步驟如下:

  (1)建立一個DLL項目。MFC提供兩種類型的動態連結程式庫:常規型DLL、擴充型DLL。其中,常規型DLL適合於非MFC開發環境下採用支援DLL調用的程式設計語言開發的應用程式,擴充型DLL只能被MFC程式使用。

  (2)建立該DLL中的過程或函數,只需在程式中加入下列語句:

extern "C" _declspec(dllexport)
int yanzheng(CString input,char* zcm)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 file://具體實現過程
}

  該函數的功能是驗證註冊碼是否合法,其中yanzheng為函數名,int為函數傳回值類型,()內為函數參數。編譯通過後即可使用。

  四、 VC中DLL的調用

  在VC中調用動態連結程式庫時,類似於Delphi中運行時調用DLL的方法。也要調用到Windows的API函數LoadLibrary,GetProcAddress等。此方法對於調用其它語言和VC編譯的DLL均適用。

  假定DLL中包括一個函數:

int yanzheng(CString input,char* zcm)

  
  首先在欲調用DLL函數的cpp檔案前部先聲明函數指標,定義函數類型:

typedef int (* _YANZHENG)(CString,char* zcm);

  然後定義如下變數∶

HINSTANCE hLibrary;
_YANZHENG yanzheng;

  在調用DLL處加入如下語句進行DLL裝載:

hLibrary=LoadLibrary("zcdll.dll");
yanzheng=(_YANZHENG)GetProcAddress(hLibrary,"yanzheng");
shuchu= (*yanzheng)(shuru,zcm);
FreeLibrary(hLibrary);

  五、 幾點提示

  (1)如果用Delphi建立DLL時用到其它的form,則在DLL的輸出函數中應包括form的create(建立)和free(釋放),而且在顯示該視窗時只能用showmodal過程,不能用show過程,在後面的例子中能詳細看到。

  (2)如果Delphi建立的DLL中的函數或過程,用string類型作為參數輸入或返回string類型,當用VC或其它程式調用時,經常會出錯,反之亦然。為瞭解決這種情況,使不同程式之間在使用字串類型時,介面更安全,建議使用pchar類型,而不是string類型。而且要在程式中加入記憶體管理,使用系統提供的sharemem單元。下面是一個實現將星期標識由數字轉換成英文的例子:

uses
sharemem;
exports
makeitaday;
var
mydate:pchar;
function makeitaday(S:integer):pchar;stdcall;export;
implementation
function makeitaday(S:integer):pchar;stdcall;export;
var
thedate:array[0..20] of char;
begin
GetMem(mydate, 200);
if s=1 then thedate:='Sunday ';
file://……….
strpcopy(mydate,thedate);
makeitaday:=mydate;
end;

 六、執行個體

  因為用Delphi建立和調用DLL,過程與用VC建立和調用DLL相似,只是前者代碼要比在VC環境中稍微複雜一些,因此在文章的最後給出一個完整的用Delphi建立和調用DLL的例子。該DLL主要用來檢查輸入的口令是否正確,表單含有一個Edit編輯框,一個按鈕Button,在編輯框內輸入口令,比較編輯框的值和輸入參數返回真假值。

//檔案名稱為checkpassword.dpr;編譯此檔案產生checkpassword.dll
library checkpassword;
uses
SysUtils, Classes, Unit1 in 'Unit1.pas' {Form1};
exports
checkpwd name 'checkpwd';//聲明DLL函數
{$R *.RES}
begin
end.

file://檔案名稱為unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
password: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
flag:boolean;//返回輸入密碼是否正確
rightpwd:string;//記錄輸入參數(正確的密碼)
function checkpwd(pwd:string):boolean;export;//聲明DLL函數
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
if password.text=rightpwd then
flag:=true;
form1.close;
end;

function checkpwd(pwd:string):boolean;export;
begin
flag:=false;
rightpwd:=pwd;//讀入正確的密碼值
form1:=Tform1.create(Application);//建立密碼驗證視窗
form1.ShowModal;//顯示視窗
checkpwd:=flag;
form1.free;//釋放資源
end;
end.

file://主程式main.pas,調用DLL
unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
jieguo: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
 public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
function checkpwd(pwd:string):boolean;external 'project1.dll' ;//函數說明
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
if checkpwd('congrong') then//調用函數
jieguo.text:='true'
else
jieguo.text:='false';
end;
end.

  以上程式在Windows98/Delphi5下編譯通過。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.