下面是我的代码,exe动态加载dll “baseinfo”,在dll的DLL_PROCESS_DETACH中写了卸载dll语句,实现dll封装的窗体关闭后就卸载dll,好节约内存,现在程序运行不报错,也没内存泄漏,就是当封装的MDI子窗体关闭后,dll不能自动卸载,还占据着内存,请教高手有什么办法能实现动态卸载dll,好节约内存。
library baseinfo;//dll的代码
uses
SysUtils,
Classes,
ADODB,
Windows,
Forms,
d_baseinfo in 'd_baseinfo.pas' {dfmBaseInfo};
var
DllApp:TApplication; //定义变量
{$R *.res}
procedure CallBaseinfo(const app:TApplication;const adocnn:Tadoconnection);stdcall;
begin
Application:=app;
if dfmBaseInfo=nil then
begin
dfmBaseInfo:=TdfmBaseInfo.Create(app);//创建mdi子窗体
dfmBaseInfo.ADOConnection1:=adocnn; //把参数adocnn对象赋给ADOConnection1获得数据库连接
end;
dfmBaseInfo.Show;
end;
procedure MyDLLProc(Reason:Integer);
begin
if Reason=DLL_PROCESS_DETACH then
begin
if Assigned(DllApp) then
Application:=DllApp;
FreeLibrary(Application.Handle); //进程退出时卸载dll
end;
end;
exports
CallBaseinfo;
begin
DllApp:=Application; //把dll的Application先存起来
DllProc:=@MyDLLProc; //
end.//exe的调用代码
type
PlugIn=function(const app:TApplication;const adocnn:Tadoconnection):integer;stdcall;
……procedure Tf_main.N3Click(Sender: TObject);
var
ahandle:THandle;
plug:PlugIn;
begin
ahandle:=LoadLibrary('baseinfo.dll') ; //动态加载DLL
try
if ahandle=0 then
exit;
@plug:=GetProcAddress(ahandle,'CallBaseinfo');
if @plug<>nil then
plug(Application,ADOConnection1);
finally
freelibrary(ahandle);
end;
end;
library baseinfo;//dll的代码
uses
SysUtils,
Classes,
ADODB,
Windows,
Forms,
d_baseinfo in 'd_baseinfo.pas' {dfmBaseInfo};
var
DllApp:TApplication; //定义变量
{$R *.res}
procedure CallBaseinfo(const app:TApplication;const adocnn:Tadoconnection);stdcall;
begin
Application:=app;
if dfmBaseInfo=nil then
begin
dfmBaseInfo:=TdfmBaseInfo.Create(app);//创建mdi子窗体
dfmBaseInfo.ADOConnection1:=adocnn; //把参数adocnn对象赋给ADOConnection1获得数据库连接
end;
dfmBaseInfo.Show;
end;
procedure MyDLLProc(Reason:Integer);
begin
if Reason=DLL_PROCESS_DETACH then
begin
if Assigned(DllApp) then
Application:=DllApp;
FreeLibrary(Application.Handle); //进程退出时卸载dll
end;
end;
exports
CallBaseinfo;
begin
DllApp:=Application; //把dll的Application先存起来
DllProc:=@MyDLLProc; //
end.//exe的调用代码
type
PlugIn=function(const app:TApplication;const adocnn:Tadoconnection):integer;stdcall;
……procedure Tf_main.N3Click(Sender: TObject);
var
ahandle:THandle;
plug:PlugIn;
begin
ahandle:=LoadLibrary('baseinfo.dll') ; //动态加载DLL
try
if ahandle=0 then
exit;
@plug:=GetProcAddress(ahandle,'CallBaseinfo');
if @plug<>nil then
plug(Application,ADOConnection1);
finally
freelibrary(ahandle);
end;
end;
解决方案 »
- 各位高手,请给我一个用ClientDataSet动态创建lookup字段的示例代码。
- 如何将一个字符串映射为一个Delphi页面控件属性名
- 如何做一个类似于windows 2000 登陆系统的程序?
- 哪位仁兄能提供IntraWeb的注册机
- 关于TTreeView-----Delphi7的bug?我的编译器出了问题?还是...我错了?
- 今天我大寿,分5贴散分1000(3 of 5),请各位自觉莫重复接分!
- 错了,错了,我是在网上下了一个DELPHI开发的应用程序,是用SERVER2000作为数据库的,我想执行应用程序,请问如何配置?
- 如何写一段代码实现数据库中编号项的自动编号?并能在输入了很多记录后用户删除某一项,在用户重新添加一项的时候能够自动找到前面被删除
- ********用oleVariant能传record吗?如何传,小弟问了好几年了???**************
- 用到接口的程序什么打包?
- 客户端用clientdataset,提示CommandText does not return a result set
- 采用运行时包 发布exe 没有采用三方控件 都需要哪些bpl ?有个清单没 ?
//exe的调用代码
type
PlugIn=function(const app:TApplication;const adocnn:Tadoconnection):integer;stdcall;
……procedure Tf_main.N3Click(Sender: TObject);
var
ahandle:THandle;
plug:PlugIn;
begin
ahandle:=LoadLibrary('baseinfo.dll') ; //动态加载DLL
if ahandle=0 then
exit;
@plug:=GetProcAddress(ahandle,'CallBaseinfo');
if @plug <>nil then
plug(Application,ADOConnection1);
end;
主程序:
procedure freelib(h:Thandle);
begin
FreeLibrary(h); //这里需要到timer中去释放,不能直接释放,否则报错。
end;procedure Tf_main.N3Click(Sender: TObject);
var
ahandle:THandle;
plug:PlugIn;
begin
ahandle:=LoadLibrary('baseinfo.dll') ;
try
if ahandle=0 then
exit;
@plug:=GetProcAddress(ahandle,'CallBaseinfo');
if @plug <>nil then
plug(Application,ADOConnection1,@freelib);
end;
动态库:
type
TMyFreeLibrary=procedure(h:Thandle);
.
.
.
procedure Tform1.FormClose(Sender: TObject;
var Action: TCloseAction);
var
freelib:TMyFreeLibrary;
begin
@freelib:=传递进来的指针;
end;
主程序:
procedure freelib(h:Thandle);
begin
FreeLibrary(h); //这里需要到timer中去释放,不能直接释放,否则报错。
end;procedure Tf_main.N3Click(Sender: TObject);
var
ahandle:THandle;
plug:PlugIn;
begin
ahandle:=LoadLibrary('baseinfo.dll') ;
try
if ahandle=0 then
exit;
@plug:=GetProcAddress(ahandle,'CallBaseinfo');
if @plug <>nil then
plug(Application,ADOConnection1,@freelib);
end;
动态库:
type
TMyFreeLibrary=procedure(h:Thandle);
.
.
.
procedure Tform1.FormClose(Sender: TObject;
var Action: TCloseAction);
var
freelib:TMyFreeLibrary;
begin
@freelib:=传递进来的指针;
end;
function OpenForm(mainForm:TForm):Longint;
var
DLLForm: TDllForm;
ptr:PLongInt;
begin
ptr:=@(Application.MainForm);
ptr^:=LongInt(mainForm);
DLLForm:= TDllForm.Create(mainForm);
Result :=longInt(DLLForm);
DLLForm.Show;
end;
里面还有一个控制释放的方法
procedure FormFree(AFormRef: Longint);
begin
if AFormRef > 0 then
TDLLForm(AFormRef).Release;
end;
通过调用窗体释放资源
调用的时候用动态还是静态与入口函数没有关系的