這里的指示字就是在聲明函數或過程時附加在例程標題之后的保留字,默認為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. |