Delphi捕捉DLL执行所抛出的异常。
先來說一下我如何寫我的Dll文件的。
先看代碼:
?
代碼 library?pub_form;uses
??SysUtils,
??Classes,
??Windows,
??Forms,
??Parameter_Object,
??frm_LoginU?in?'..\公用庫單元\frm_LoginU.pas'?{frm_Login},
??pub_Event?in?'..\公用庫單元\pub_Event.pas',
??Dll_LIB_ConstU?in?'..\公用庫單元\Dll_LIB_ConstU.pas';
var
??DLLApp:?TApplication;
{begin-----------------------登錄窗體相關-------------------------}
procedure?Login(var?mLoginParam:?TLoginParam);?export;
begin
??{獲取調用窗體的Application,顯而易見的功能是?能使你的窗體融合到調用程序中。通過它還能進行很多操作}
??Application?:=?mLoginParam.App;?//將DLL的Application轉為App
??if?frm_Login?=?nil?then
????frm_Login?:=?Tfrm_Login.Create(mLoginParam.ParentForm);
??frm_Login.DoLoginClick?:=?mLoginParam.DoLogin;
??frm_Login.DoErrCatch:=mLoginParam.ErrDo;
??frm_Login.E_User.Text:=mLoginParam.OldUser;
??frm_Login.ShowModal;
end;
procedure?CloseLogin;?export;
begin
??if?frm_Login.Showing?then
????frm_Login.Close;
end;
{end-----------------------登錄窗體相關-------------------------}
{重寫Dll入口函數,否則程序會出錯}
procedure?DLLUnloadProc(Reason:?Integer);?register;
begin
??{DLL取消調用時,發送DLL_PROCESS_DETACH消息,此時將DLL的Application返回為本身}
??if?Reason?=?DLL_PROCESS_DETACH?then?Application?:=?DLLApp;
end;
exports
??Login,CloseLogin;
begin
??{在DLL入口預先儲存DLL的Application}
??DLLApp?:=?Application;
??{DllProc:DLL入口函數指針。Delphi定義為?DllProc:?TDLLProc;}
??{在此指向我們自己定義的函數}
??DLLProc?:=?@DLLUnloadProc;
end.
?
代碼中都有注釋了,這個不多說了,說一下Login的過程,我這里是直接傳遞對象指針進來。這個對象的定義在下面的代碼中:
?
代碼 unit?Parameter_Object;{
調用DLL的參數對象類
}
interface
uses
??pub_Event,Forms;
type
??TDllFormParam=class(TObject)
??public
????App:?TApplication;
????ParentForm:TForm;
????ErrDo:TExceptionEvent;
????constructor?CreateByObject(var?mApp:?TApplication;var?mParentForm:TForm;mErrDo:TExceptionEvent);
??end;
??TLoginParam=class(TDllFormParam)
??public
????DoLogin:TLoginClickEvent;
????OldUser:String;//上次登錄的用戶
????constructor?CreateByObject(var?mApp:?TApplication;var?mParentForm:TForm;mErrDo:TExceptionEvent;mDoLogin:TLoginClickEvent;mUser:string='');
??end;
implementation
{?TLoginParam?}
constructor?TLoginParam.CreateByObject(var?mApp:?TApplication;
???var?mParentForm:?TForm;mErrDo:TExceptionEvent;?mDoLogin:?TLoginClickEvent;mUser:string='');
begin
??inherited?CreateByObject(mApp,mParentForm,mErrDo);
??DoLogin:=mDoLogin;
??OldUser:=mUser;
end;
{?TDllFormParam?}
constructor?TDllFormParam.CreateByObject(var?mApp:?TApplication;
??var?mParentForm:?TForm;mErrDo:TExceptionEvent);
begin
??App:=mApp;
??ParentForm:=mParentForm;
??ErrDo:=mErrDo;
end;
end.
?
?
這樣做的好處是不用那么多參數出現,也方便動態的調用方式。
還有一個不太重要的單元:
?
unit?pub_Event;interface
uses
??SysUtils;
type
??//點擊登錄按鈕時觸發外部檢測帳號與密碼是否正確
??TLoginClickEvent?=?procedure(UserName,?UserPW:?string)?of?object;
implementation
end.
?
下面是這個登錄傳遞的源碼:
?
代碼 unit?frm_LoginU;interface
uses
??Windows,?Messages,?SysUtils,?Variants,?Classes,?Graphics,?Controls,?Forms,
??Dialogs,?StdCtrls,?pub_Event;
type
??Tfrm_Login?=?class(TForm)
????E_User:?TEdit;
????E_PassWD:?TEdit;
????btn_Login:?TButton;
????btn_Exit:?TButton;
????procedure?FormKeyPress(Sender:?TObject;?var?Key:?Char);
????procedure?btn_ExitClick(Sender:?TObject);
????procedure?btn_LoginClick(Sender:?TObject);
????procedure?FormClose(Sender:?TObject;?var?Action:?TCloseAction);
??private
????{?Private?declarations?}
??public
????{?Public?declarations?}
????DoLoginClick:?TLoginClickEvent;
????DoErrCatch:TExceptionEvent;
??end;
var
??frm_Login:?Tfrm_Login;
implementation
{$R?*.dfm}
procedure?Tfrm_Login.FormKeyPress(Sender:?TObject;?var?Key:?Char);
begin
??if?key?=?#13?then
??begin
????Key?:=?#0;
????Keybd_Event(VK_TAB,?0,?0,?0);
??end;
end;
procedure?Tfrm_Login.btn_ExitClick(Sender:?TObject);
begin
??self.close;
end;
procedure?Tfrm_Login.btn_LoginClick(Sender:?TObject);
begin
??if?Assigned(DoLoginClick)?then
??begin
????try
????DoLoginClick(trim(E_User.Text),?Trim(E_PassWD.Text));
????except???on???e:Exception???do
??????DoErrCatch(sender,e);
????end;
??end;
end;
procedure?Tfrm_Login.FormClose(Sender:?TObject;?var?Action:?TCloseAction);
begin
??Action:=caFree;
end;
end.
?
?
全部都出來了,我說下我這個DLL的登錄驗證窗體的工作方式:把登錄的驗證方法放在主程序里面,因為,不同時期不同的開發項目,其登錄驗證方式都不一樣,因此獨立出主程序里,采用回調的方式來實現。由于登錄窗體需要到數據庫中去驗證帳號和密碼,因此,我特意把字段輸錯,這里所報的異常不會被主程序捕捉到,為何不會被主程序捕捉到?我猜是因為調用這個驗證方法是一個DLL,而DLL畢竟不是主程序,因此,其錯誤消息是不會被主程序所捕捉到的,就算開始的時候把application傳到了dll里面去也一樣捕捉不到(如果能捕捉到的,請把方法告訴我,我找了很久都沒找到相關的資料),在網上找了個資料,網址是:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3660866
根據這個提示,我把異常處理的方法也傳進去了,這樣,在驗證登錄方法時出錯了,也能調用主程序中的捕捉異常的方法。
?
原創作品出自努力偷懶,轉載請說明文章出處:http://www.cnblogs.com/kfarvid/
轉載于:https://www.cnblogs.com/kfarvid/archive/2010/08/06/1794307.html
總結
以上是生活随笔為你收集整理的Delphi捕捉DLL执行所抛出的异常。的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 方法重载简单小例子
- 下一篇: bzoj 1024 [ SCOI 200