关于dbexpress放入dll中使用后出现的异常 程序由MainForm和formDLL组成:(formDLL是一个DLL文件)
功能:MainForm调用formDLL,对数据表testtable进行操作.MainForm包含一个sqlcnt组件(TSqlConnection)(连接至SQL2K 数据库)formDLL包含,conn组件(TSqlConnection),dsp组件(TDataSetProvide),cds组件(TClientDataSet),sqy组件(TSqlQuery),
ds组件(TDataSource),dg组件(TDataGrid);
sqy.sql为select col1,col2,col3 from testtable
conn直接引用MainForm中的Sqlcnt.
sql.connection:=conn;
这些组件互相连接,MainForm调用formDll正常.对formDll进行操作:
cds.Active:= true时,
dg中可以正常显示数据.保存数据至数据表时(cds.ApplyUpdate(0)),分两种情况:
情况A:当插入的数据,在数据表中不存在,因此可以正常操作,数据可以正常保存至数据表中.
情况B:当插入的数据,已存在于数据表中,此时,利用cds的OnReconcileError事件,可以捕捉到错误代码ErrorCode为1(即此数据已存在数据表中).捕捉到错误后,什么都不做,只显示我自定义的警告信息"此数据已存在".退出formDll正常(至少表面没有弹出什么异常信息).
formDll.Free;
formDll:=nil;操作就如上所述这么简单.问题出在:当退出应用程序时,情况A,程序可以正常退出.
但是,一旦在操作formDll时出现过情况B,那么退出应用程序时,就一定会提示异常,
异常信息为: "0x004b3bd2"指令引的"0x00d5c5f0"内存,该内存不能为"read"
点击确定后,又弹出对话框:Runtime error 216 at 004b3bd2.应用程序环境为xp(sp2),bds2006(update 2),delphi.由于对DLL是初级接触,不知道什么地方会有问题.希望大家能参详参详.
在此先谢谢大家了!DLL源码如下://WhoInOut.dllunit utEditWhoInOut;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, DBXpress, WideStrings, DB, SqlExpr, Grids, DBGrids,
  Provider, DBClient, FMTBcd, GridsEh, DBGridEh, ActnList, ExtCtrls, StdCtrls,
  Mask, DBCtrls;type
  TfmEditWhoInOut = class(TForm)
    sbtnAdd: TSpeedButton;
    sbtnExit: TSpeedButton;
    ds: TDataSource;
    cds: TClientDataSet;
    dsp: TDataSetProvider;
    sqy: TSQLQuery;
    cdsfnum: TStringField;
    cdsFname: TWideStringField;
    cdsFaddress: TWideStringField;
    cdsFphone: TStringField;
    cdsFman: TWideStringField;
    cdsFclass: TStringField;
    cdsfother: TWideStringField;
    dg: TDBGridEh;
    actlst: TActionList;
    actInsert: TAction;
    lb: TLabel;
    dbedtNum: TDBEdit;
    lb2: TLabel;
    DBEdit2: TDBEdit;
    lb3: TLabel;
    DBEdit3: TDBEdit;
    lb4: TLabel;
    DBEdit4: TDBEdit;
    lb5: TLabel;
    DBEdit5: TDBEdit;
    lb6: TLabel;
    DBEdit6: TDBEdit;
    lb7: TLabel;
    DBEdit7: TDBEdit;
    sbtnSave: TSpeedButton;
    sbtnClose: TSpeedButton;
    actInsertSave: TAction;
    procedure sbtnExitClick(Sender: TObject);
    procedure actInsertSaveExecute(Sender: TObject);
    procedure actInsertExecute(Sender: TObject);
    procedure cdsReconcileError(DataSet: TCustomClientDataSet;
      E: EReconcileError; UpdateKind: TUpdateKind;
      var Action: TReconcileAction);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);  private
    { Private declarations }  public
    { Public declarations }
  end;var
  fmEditWhoInOut: TfmEditWhoInOut;
  conn:TSqlConnection;  //引用SQLconnection连接
  myCaption:string;function GetFmWhoInOut(var sqlcntlog:TSQLConnection):integer;stdcall; 
//主程序利用这个函数来调用dll中的Form
exports GetFmWhoInOut;implementation{$R *.dfm}function GetFmWhoInOut(sqlcntlog:TSQLConnection):integer;stdcall;
begin
  result:=1;
  fmEditWhoInOut:=TfmEditWhoInOut.Create(Application);
  try      conn:=sqlcntlog;
      fmEditWhoInOut.sqy.SQLConnection :=conn;
      fmEditWhoInOut.sqy.sql.add('select * from tb');
      fmEditWhoInOut.ShowModal;
      result:=0;  finally
    fmEditWhoInOut.Free;
    fmEditWhoInOut:=nil;
  end;
end;
procedure TfmEditWhoInOut.actInsertExecute(Sender: TObject);
begin
        cds.active := true;
        cds.Append;
end;procedure TfmEditWhoInOut.actInsertSaveExecute(Sender: TObject);
begin
    if cds.ApplyUpdates(0)=0 then
    begin
        if (MessageBox(0, '信息保存成功!'+#13+#10+'是否继续添加新的记录?',
            '提示', MB_ICONQUESTION or MB_YESNO) =idYes)  then
        begin
          cds.Insert;
        end;
    end;end;procedure TfmEditWhoInOut.cdsReconcileError(DataSet: TCustomClientDataSet;
  E: EReconcileError; UpdateKind: TUpdateKind; var Action: TReconcileAction);
begin
  if E.ErrorCode = 1 then
  begin
      MessageBox(0, '此数据已存在,无法添加此数据!'+#13+#10+'修改此数据请先返回.', '警告', MB_ICONWARNING or MB_OK);
  end
  else
    MessageDlg('错误代码:', mtError, [mbOK], 0);  Action:=raSkip;
end;procedure TfmEditWhoInOut.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  cds.Active := false;
  conn:=nil;
end;procedure TfmEditWhoInOut.sbtnExitClick(Sender: TObject);
begin
  self.Close;
end;end.
调用dll的主程序代码如下:
//sqlcnt是一个TSqlConnection组件,属性都已正确设置完毕
//多余代码已省略.我是用静态调用的方式来调用DLL的.procedure TForm1.actGetWhoInOutExecute(Sender: TObject);
begin
try
    GetFmWhoInOut(sqlcnt); //调用dll中的GetFmWhoInOut,来显示DLL中的FORM.
except
  MessageDlg('catch dll error', mtWarning, [mbOK], 0);end;
end;//我试着想捕捉DLL的异常,但是无法捕捉,不知道我这样的捕捉方式是否正确?.
这个问题困扰我很久了,希望高手能指点一下.谢谢