Delphi捕捉DLL执行所抛出的异常。
Posted 朝闻道
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Delphi捕捉DLL执行所抛出的异常。相关的知识,希望对你有一定的参考价值。
先来说一下我如何写我的Dll文件的。
先看代码:
代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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的过程,我这里是直接传递对象指针进来。这个对象的定义在下面的代码中:
代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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.
这样做的好处是不用那么多参数出现,也方便动态的调用方式。
还有一个不太重要的单元:
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->unit pub_Event; interface uses SysUtils; type //点击登录按钮时触发外部检测帐号与密码是否正确 TLoginClickEvent = procedure(UserName, UserPW: string) of object; implementation end.
下面是这个登录传递的源码:
代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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/
http://www.cnblogs.com/kfarvid/archive/2010/08/06/1794307.html
以上是关于Delphi捕捉DLL执行所抛出的异常。的主要内容,如果未能解决你的问题,请参考以下文章