我写了个dll,运行时会不定时出错,希望高手赐教。
//dll单元
unit U_dll_filter;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Wwdatsrc, StdCtrls, Buttons;type
TFm_filter = class(TForm)
ComBox_field1: TComboBox;
...
BitBtn_ok: TBitBtn; //kind:bkok
BitBtn_cancel: TBitBtn; //kind:bkCancel
end;function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;StdCall;implementation{$R *.dfm}function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;
var
fm_filter:TFm_filter;
filter_strlst:tstringlist;
filter_str:string;
begin
application.Handle:=ahandle;
try
fm_filter:=tfm_filter.Create(application);
filter_strlst:=tstringlist.Create;
filter_str:='';
...
if fm_filter.ComBox_Field1.ItemIndex=0 then
... //do something
result:=filter_str;
finally
fm_filter.Free;
end;
end;end.
------------------------宿主程序单元
unit U_main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, wwSpeedButton, wwDBNavigator, ExtCtrls, wwclearpanel,
Grids, Wwdbigrd, Wwdbgrid, DB, Wwdatsrc, ADODB,WinTypes, WinProcs;type
Tdata_filter = function (ahandle:thandle;wwDsrc_filter:twwdatasource):string;stdcall;
EDLLLoadError = class(Exception); TForm_main = class(TForm)
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
wwDS_table: TwwDataSource;
wwDBGrid1: TwwDBGrid;
wwDBNavigator1: TwwDBNavigator;
...
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;var
Form_main: TForm_main;implementation{$R *.dfm}procedure TForm_main.Button1Click(Sender: TObject);
var
LibHandle : THandle;
data_filter:Tdata_filter;
begin
LibHandle := LoadLibrary('filter_source.dll');
try
if LibHandle = 0 then
raise EDLLLoadError.Create('Unable to Load DLL'); @data_filter := GetProcAddress(LibHandle, 'func_filter'); if not (@data_filter = nil) then
begin
adotable1.Filter:=data_filter(application.Handle,wwDS_table);
adotable1.Close;
adotable1.Filtered:=true;
adotable1.Open;
endfinally
FreeLibrary(LibHandle);
end;end.如果不把FreeLibrary(LibHandle)注释掉,运行一次就出错;注释掉,2至3次后出错。如果写作:
//dll单元
unit U_dll_filter;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Wwdatsrc, StdCtrls, Buttons;type
TFm_filter = class(TForm)
ComBox_field1: TComboBox;
...
BitBtn_ok: TBitBtn; //kind:bkok
BitBtn_cancel: TBitBtn; //kind:bkCancel
end;function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;export;implementation{$R *.dfm}function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;
var
fm_filter:TFm_filter;
filter_strlst:tstringlist;
filter_str:string;
begin
application.Handle:=ahandle;
try
fm_filter:=tfm_filter.Create(application);
filter_strlst:=tstringlist.Create;
filter_str:='';
...
if fm_filter.ComBox_Field1.ItemIndex=0 then
... //do something
result:=filter_str;
finally
fm_filter.Free;
end;
end;end.
------------------------宿主程序单元
unit U_main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, wwSpeedButton, wwDBNavigator, ExtCtrls, wwclearpanel,
Grids, Wwdbigrd, Wwdbgrid, DB, Wwdatsrc, ADODB,WinTypes, WinProcs;type TForm_main = class(TForm)
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
wwDS_table: TwwDataSource;
wwDBGrid1: TwwDBGrid;
wwDBNavigator1: TwwDBNavigator;
...
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;var
Form_main: TForm_main;
function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;external 'P_dll_filter';
implementation{$R *.dfm}procedure TForm_main.Button1Click(Sender: TObject);
begin
adotable1.Filter:=data_filter(application.Handle,wwDS_table);
adotable1.Close;
adotable1.Filtered:=true;
adotable1.Open;
end;end.则可以运行多次,但超过3~4次后很容易出错。
//dll单元
unit U_dll_filter;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Wwdatsrc, StdCtrls, Buttons;type
TFm_filter = class(TForm)
ComBox_field1: TComboBox;
...
BitBtn_ok: TBitBtn; //kind:bkok
BitBtn_cancel: TBitBtn; //kind:bkCancel
end;function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;StdCall;implementation{$R *.dfm}function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;
var
fm_filter:TFm_filter;
filter_strlst:tstringlist;
filter_str:string;
begin
application.Handle:=ahandle;
try
fm_filter:=tfm_filter.Create(application);
filter_strlst:=tstringlist.Create;
filter_str:='';
...
if fm_filter.ComBox_Field1.ItemIndex=0 then
... //do something
result:=filter_str;
finally
fm_filter.Free;
end;
end;end.
------------------------宿主程序单元
unit U_main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, wwSpeedButton, wwDBNavigator, ExtCtrls, wwclearpanel,
Grids, Wwdbigrd, Wwdbgrid, DB, Wwdatsrc, ADODB,WinTypes, WinProcs;type
Tdata_filter = function (ahandle:thandle;wwDsrc_filter:twwdatasource):string;stdcall;
EDLLLoadError = class(Exception); TForm_main = class(TForm)
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
wwDS_table: TwwDataSource;
wwDBGrid1: TwwDBGrid;
wwDBNavigator1: TwwDBNavigator;
...
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;var
Form_main: TForm_main;implementation{$R *.dfm}procedure TForm_main.Button1Click(Sender: TObject);
var
LibHandle : THandle;
data_filter:Tdata_filter;
begin
LibHandle := LoadLibrary('filter_source.dll');
try
if LibHandle = 0 then
raise EDLLLoadError.Create('Unable to Load DLL'); @data_filter := GetProcAddress(LibHandle, 'func_filter'); if not (@data_filter = nil) then
begin
adotable1.Filter:=data_filter(application.Handle,wwDS_table);
adotable1.Close;
adotable1.Filtered:=true;
adotable1.Open;
endfinally
FreeLibrary(LibHandle);
end;end.如果不把FreeLibrary(LibHandle)注释掉,运行一次就出错;注释掉,2至3次后出错。如果写作:
//dll单元
unit U_dll_filter;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Wwdatsrc, StdCtrls, Buttons;type
TFm_filter = class(TForm)
ComBox_field1: TComboBox;
...
BitBtn_ok: TBitBtn; //kind:bkok
BitBtn_cancel: TBitBtn; //kind:bkCancel
end;function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;export;implementation{$R *.dfm}function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;
var
fm_filter:TFm_filter;
filter_strlst:tstringlist;
filter_str:string;
begin
application.Handle:=ahandle;
try
fm_filter:=tfm_filter.Create(application);
filter_strlst:=tstringlist.Create;
filter_str:='';
...
if fm_filter.ComBox_Field1.ItemIndex=0 then
... //do something
result:=filter_str;
finally
fm_filter.Free;
end;
end;end.
------------------------宿主程序单元
unit U_main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, wwSpeedButton, wwDBNavigator, ExtCtrls, wwclearpanel,
Grids, Wwdbigrd, Wwdbgrid, DB, Wwdatsrc, ADODB,WinTypes, WinProcs;type TForm_main = class(TForm)
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
wwDS_table: TwwDataSource;
wwDBGrid1: TwwDBGrid;
wwDBNavigator1: TwwDBNavigator;
...
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;var
Form_main: TForm_main;
function func_filter(ahandle:thandle;wwDsrc_filter:twwdatasource):string;external 'P_dll_filter';
implementation{$R *.dfm}procedure TForm_main.Button1Click(Sender: TObject);
begin
adotable1.Filter:=data_filter(application.Handle,wwDS_table);
adotable1.Close;
adotable1.Filtered:=true;
adotable1.Open;
end;end.则可以运行多次,但超过3~4次后很容易出错。
的返回值要用pchar
如果dll中包含了ado控件,要把ActiveX单元包含到dll工程中,并且在卸载dll时,要把所有的AdoQuery等关闭,否则报错
如果我把BitBtn_ok的kind设为bkok,那么我点击这个按钮时,dll是否会自动释放form呢?
我定义的tstringlist对象是否仍然必须手动释放?
的返回值要用pchar"能告诉我为什么吗?谢谢。