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 = # then
begin
Key := #;
Keybd_Event(VK_TAB, , , );
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执行所抛出的异常。的更多相关文章
- 捕获Java线程池执行任务抛出的异常
捕获Java线程池执行任务抛出的异常Java中线程执行的任务接口java.lang.Runnable 要求不抛出Checked异常, public interface Runnable { publi ...
- 想抛就抛:Application_Error中统一处理ajax请求执行中抛出的异常
女朋友不是想抛就抛,但异常却可以,不信请往下看. 今天在MVC Controller中写代码时,纠结了一下: public async Task<ActionResult> Save(in ...
- 外部无法捕捉Realm的doGetAuthenticationInfo方法抛出的异常
shiro权限框架,用户登录方法的subject.login(token)会进入自定义的UserNamePasswordRealm类的doGetAuthenticationInfo身份验证方法 通常情 ...
- 应该抛出什么异常?不应该抛出什么异常?(.NET/C#)
我在 .NET/C# 建议的异常处理原则 中描述了如何 catch 异常以及重新 throw.然而何时应该 throw 异常,以及应该 throw 什么异常呢? 究竟是谁错了? 代码中从上到下从里到外 ...
- druid抛出的异常------javax.management.InstanceAlreadyExistsException引发的一系列探索
最近项目中有个定时任务的需求,定时检查mysql数据与etcd数据的一致性,具体实现细节就不说了,今天要说的就是实现过程中遇到了druid抛出的异常,以及解决的过程 异常 异常详细信息 五月 05, ...
- Java中主线程如何捕获子线程抛出的异常
首先明确线程代码的边界.其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界.Runnable接口中run方法原型如下: public void run(); 而所有的具 ...
- 记录一次dubbo不能正常抛出特定异常
BUG场景 今天同事的代码中出现一个问题,让我帮忙排查一下.原代码大致如下 dubbo服务消费者: @Resource private IPayWayService payWayService; @R ...
- 将Controller抛出的异常转到特定View
<!-- 将Controller抛出的异常转到特定View --> <bean class="org.springframework.web.servlet.handler ...
- 使用visual studio 2015调用阿里云oss .net sdk 2.2的putobject接口抛出outofmemory异常
问题描述: 使用阿里云oss .net sdk 2.2版本,使用putobject接口上传文件时,抛出outofmemory异常. 原因分析: 上传时,用于准备上传的数据缓冲区内存分配失败.与应用软件 ...
随机推荐
- Meteor错误:TypeError: Meteor.userId is not a function
问题描述: 浏览器console提示错误TypeError: Meteor.userId is not a function. 原因分析: 通过查看Meteor API文档,可知该函数由包accoun ...
- 在XP系统下搭建maven环境出的问题 Unable to locate the Javac Compiler in: C:\Program Files\Java\jre6\..\lib\tools.jar
Build errors for spider; org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute g ...
- iOS NSMutableArray替换某个元素
A * a1 = [A new]; A * a2 = [A new]; A * a3 = [A new]; A * a4 = [A new]; NSMutableArray *arr = [[NSMu ...
- 关于修改tabbar的颜色的问题
首先,项目是在故事板中搭建的,所以遇到这个问题的时候,首先是想到在故事板中找到相关的属性,确实是有一个Selected Image,但是设置了这个图片以后,运行的效果是,点击选择后,本身的image就 ...
- ios开发之UIView的frame、bounds跟center属性的区别(附图)
博文暂时想到什么写什么,不顺理成章,不顺章成篇. 先看几个概念 坐标点Poit:向右侧为X轴正方向的值x,原点下侧为Y轴正方向的值y 大小Size:由宽度width和高度height构成,表示一个矩形 ...
- 启发式搜索 A*算法的OC 实现
前两天重新学习了下A*算法,上次学习A*算法已经是5年前了,看到网上铺天盖地的A*算法都是C.C++等等其他语言的,就是没有OC 的,所以抽空写了一份.今天太晚了就不说明A*算法的细节了,大家如果想学 ...
- 文件上传~Uploadify上传控件
对于文件上传来说,有很多种实现方式,如传统的表单方式,现在流行的flash方式,甚至还有纯JS方式,之所以有这些方式来实现文件上传,我想主要原因是因为,传统的上传对于大文件支持不够,因为它是单线程同步 ...
- Installation Phases and In-Script Execution for Custom Actions in Windows Installer
用 InstallShield 依照 Custom Action Wizard 创建 Custom Action 时,会遇到下面的几个选项: In-Script Execution Install U ...
- jquery 在页面中按回车 响应 事件
为了用户方便我们往往会在用户回车之后做一些事,比如登陆的时候,填完表单过后,我们习惯性的会直接按回车,当然要处理这个,jquery是很简单的,我们来看看怎么做吧. $(document).ready( ...
- Cassandra1.2文档学习(8)—— 数据管理
数据参考:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/dml/dml_manage ...