Delphi中高級DLL的編寫和調用 |
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
此為轉貼資料 Delphi中高級DLL的編寫和調用
根據Delphi提供的有關 DLL編寫和調用的幫助資訊,你可以很快完成一般的 DLL編寫和調用的 應用程式。本文介紹的主題是如何編寫和調用能夠傳遞各種參數(包括物件實例)的 DLL。例如, 主叫程式傳遞給 DLL一個ADOConnection 物件示例作?參數, DLL中的函數和程式呼叫通過該物件 實例訪問資料庫。
需要明確一些基本概念。對於 DLL,需要在主程序中包含 exports子句,用於向外界提供調用 介面,子句中就是一系列函數或過程的名字。對於主叫方(調用 DLL的應用程式或其他的 DLL), 則需要在調用之前進行外部聲明,即external保留字指示的聲明。這些是編寫 DLL和調用 DLL必須 具備的要素。
另外需要瞭解Object Pascal 中有關調用協定的內容。在Object Pascal 中,對於過程和函數 有以下五種調用協定:
指示字 參數傳遞順序 參數清除者 參數是否使用寄存器
register 自左向右 被調常式 是
pascal 自左向右 被調常式 否
cdecl 自右向左 調用者 否
stdcall 自右向左 被調常式 否
safecall 自右向左 被調常式 否
這裏的指示字就是在聲明函數或過程時附加在常式標題之後的保留字,默認?register,即是 唯一使用 CPU寄存器的參數傳遞方式,也是傳遞速度最快的方式;
· pascal: 調用協定僅用於向後相容,即向舊的版本相容;
· cdecl: 多用於 C和 C 語言編寫的常式,也用於需要由調用者清除參數的常式;
· stdcall: 和safecall主要用於調用Windows API 函數;其中safecall還用於雙重介面。
在本例中,將使用調用協定cdecl ,因?被調用的 DLL中,使用的資料庫連接是由主叫方傳遞 得到的,並且需要由主叫方處理連接的關閉和銷毀。
下面是 DLL完整根源程式和主叫程式完整根源程式。包括以下四個文件: Project1.DPR {主叫程式}
Unit1.PAS {主叫程式單元}
Project2.DPR {DLL}
Unit2.PAS {DLL單元} {---------- DLL 主程序 Project2.DPR ----------} library Project2; uses
SysUtils,
Classes,
Unit2 in 'Unit2.pas' {Form1}; {$R *.RES} { 下面的語句用於向調用該 DLL的程式提供調用介面 }
exports
DoTest; { 過程來自單元Unit2 } begin
end. {---------- DLL中的單元 Unit2.PAS ----------} unit Unit2; interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, ADODB, StdCtrls, Menus; type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;{ 本地資料庫連接 }
Memo1: TMemo; { 用於顯示資訊 }
private
public
end; { 該過程向外提供 }
procedure DoTest(H: THandle; { 獲得調用者的控制碼 }
AConn: TADOConnection;{ 獲得調用者的資料庫連接 }
S: string; { 獲得一些文本資訊 }
N: Integer); { 獲得一些數值資訊 }
cdecl; { 指定調用協定 } implementation {$R *.DFM} procedure DoTest(H: THandle; AConn: TADOConnection; S: string; N: Integer);
begin
Application.Handle := H; { 將過程的控制碼賦值?調用者的控制碼 }
{ 上面語句的作用在於, DLL的控制碼和調用者的控制碼相同,在任務欄中就不會 }
{ 各自出現一個任務標題了。 }
with TForm1.Create(Application) do try{ 創建表單 }
Memo1.Lines.Append('成功調用'); { 顯示一行資訊 }
ADOConnection1 := AConn; { 獲得資料庫連接的實例 }
Memo1.Lines.Append(
ADOConnection1.ConnectionString
' - ' S ' - ' IntToStr(N)); { 根據得到的參數顯示另一行資訊 }
ShowModal; { 模式化顯示表單 }
finally
Free; { 調用結束時銷毀窗口 }
end;
end; end. {---------- 調用者 Project1.DPR,很普通的工程文件 ----------} program Project1; uses
Forms,
Unit1 in 'Unit1.pas' {Form1}; {$R *.RES} begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end. {---------- 調用者單元Unit1.PAS ----------} unit Unit1; interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Db, ADODB; type
TForm1 = class(TForm)
Button1: TButton; { 按此按鈕進行調用 }
ADOConnection1: TADOConnection; { 本地資料庫連接,將傳遞給 DLL }
procedure Button1Click(Sender: TObject);{ 調用 DLL}
private
public
end; var
Form1: TForm1; implementation {$R *.DFM} { 外部聲明必須和 DLL中的參數列表一致,否則會運行時錯誤 }
procedure DoTest(H: THandle; { 傳遞控制碼 }
AConn: TADOConnection; { 傳遞資料庫連接 }
S: string; { 傳遞文本資訊 }
N: Integer); { 傳遞數值資訊 }
cdecl; { 指定調用協定 }
external 'Project2.dll';{ 指定過程來源 } { 調用過程 }
procedure TForm1.Button1Click(Sender: TObject);
begin
DoTest(Application.Handle,
ADOConnection1,
'Call OK',
256);
end; end. 發表人 - JACKKCG 於 2002/10/26 01:49:08
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |