调用dll窗体退出调用主程序时出错 ( 积分: 100 )

  • 主题发起人 主题发起人 zwwhb
  • 开始时间 开始时间
Z

zwwhb

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了一个dll,这个dll实际是一个功能很全的exe,只不过将其封装成了DLL,里面有数据库的连接及其他一些功能模块。我的主窗体要调用dll中的主窗体。程序大致是这样的:
dll工程
library Scan;

uses
sharemem,
SysUtils,
Forms,
Windows,
Messages,
Classes,
ScanForm in 'ScanForm.pas' {FrmScan},
UDM in 'UDM.pas' {DM: TDataModule},
Common in 'Common.pas',
Qryxsjbqk in 'Qryxsjbqk.pas' {FrmQryxsjbqk},
SearchClue in 'SearchClue.pas' {FrmSearchClue};

{$R *.res}
exports
CreateDLLTest;
begin

end.

dll主窗体及相关事件:
unit scanform;
interface
uses
......
procedure CreateDLLTest(p_xsdjh,p_xsmc,p_smry,p_dwbm:String);stdcall;
type
TFrmScan = class(TForm)
LEADTwain1: TLEADTwain;
..................
end;
var
FrmScan: TFrmScan;
implementation
procedure CreateDLLTest(p_xsdjh,p_xsmc,p_smry,p_dwbm:String);stdcall;
var FrmScan : tFrmScan;
begin
DM := TDM.Create(application)
//dll中的数据模块。
xsdjh := p_xsdjh

xsmc := p_xsmc;
smry := p_smry;
dwbm := p_dwbm
//xsdjh,xsmc,smry,dwbm均为dll中的全局变量,string类型。
FrmScan:=TFrmScan.Create(application);
FrmScan.show;

end;

procedure TFrmScan.FormClose(Sender: TObject
var Action: TCloseAction);
begin
FreeAndNIl(DM);//主窗体关闭时释放datamodule.
action := cafree;
end;

调用的主窗体
implementation

uses UDMTest;
procedure CreateDLLTest(p_xsdjh,p_xsmc,p_smry,p_dwbm:String);stdcall;external 'Scan.dll' name 'CreateDLLTest';

procedure TForm1.Button2Click(Sender: TObject);
var
xsdjh,xsmc : String;
begin
xsdjh := DmTest.Cdsxsjbqk.fieldbyname('xsdjh').asstring;
xsmc := DmTest.Cdsxsjbqk.fieldbyname('xsmc').asstring;
CreateDLLTest(xsdjh,xsmc,'zzzqqq','441000');
end;
如果在退出dll之前就退出了调用的主程序,则程序会报“a call to an os function failed”的错误。如果先退出dll,再退出调用的主程序,则不会报错。大家帮我看看什么原因
 
我写了一个dll,这个dll实际是一个功能很全的exe,只不过将其封装成了DLL,里面有数据库的连接及其他一些功能模块。我的主窗体要调用dll中的主窗体。程序大致是这样的:
dll工程
library Scan;

uses
sharemem,
SysUtils,
Forms,
Windows,
Messages,
Classes,
ScanForm in 'ScanForm.pas' {FrmScan},
UDM in 'UDM.pas' {DM: TDataModule},
Common in 'Common.pas',
Qryxsjbqk in 'Qryxsjbqk.pas' {FrmQryxsjbqk},
SearchClue in 'SearchClue.pas' {FrmSearchClue};

{$R *.res}
exports
CreateDLLTest;
begin

end.

dll主窗体及相关事件:
unit scanform;
interface
uses
......
procedure CreateDLLTest(p_xsdjh,p_xsmc,p_smry,p_dwbm:String);stdcall;
type
TFrmScan = class(TForm)
LEADTwain1: TLEADTwain;
..................
end;
var
FrmScan: TFrmScan;
implementation
procedure CreateDLLTest(p_xsdjh,p_xsmc,p_smry,p_dwbm:String);stdcall;
var FrmScan : tFrmScan;
begin
DM := TDM.Create(application)
//dll中的数据模块。
xsdjh := p_xsdjh

xsmc := p_xsmc;
smry := p_smry;
dwbm := p_dwbm
//xsdjh,xsmc,smry,dwbm均为dll中的全局变量,string类型。
FrmScan:=TFrmScan.Create(application);
FrmScan.show;

end;

procedure TFrmScan.FormClose(Sender: TObject
var Action: TCloseAction);
begin
FreeAndNIl(DM);//主窗体关闭时释放datamodule.
action := cafree;
end;

调用的主窗体
implementation

uses UDMTest;
procedure CreateDLLTest(p_xsdjh,p_xsmc,p_smry,p_dwbm:String);stdcall;external 'Scan.dll' name 'CreateDLLTest';

procedure TForm1.Button2Click(Sender: TObject);
var
xsdjh,xsmc : String;
begin
xsdjh := DmTest.Cdsxsjbqk.fieldbyname('xsdjh').asstring;
xsmc := DmTest.Cdsxsjbqk.fieldbyname('xsmc').asstring;
CreateDLLTest(xsdjh,xsmc,'zzzqqq','441000');
end;
如果在退出dll之前就退出了调用的主程序,则程序会报“a call to an os function failed”的错误。如果先退出dll,再退出调用的主程序,则不会报错。大家帮我看看什么原因
 
没人,自己顶
 
退出调用主程序前一定要释放dll呀,作一些善后处理呀
 
如何释放啊?
 
我是静态加载,并非动态装载dll
 
你这样退出报错是正常的,你最好是限制用户,在退出弹出的窗体前,不让关闭程序。
将FrmScan.show;语句改成FrmScan.showmodal;试试看。
 
难道没有其他的解决办法吗?我想实现主程序退出时DLL也自动关闭退出。
 
其实你的问题不是很复杂,你把string类型转换成PChar类型,一般就不会有这个错误,当然别忘了把sharemem去掉,因为在DLL里面使用String变量是很容易出现问题的,需要用Sharemem,还要和borlandmm.dll一起发布才能正常使用
 
在DLL和主程序中定义一个事件,当主程序退出的时候,主程序想所有自己调用的DLL发送关闭事件,让所有的DLL都关闭。然后主程序在关闭。
 
后退
顶部