M
mentoro
Unregistered / Unconfirmed
GUEST, unregistred user!
我上网查了好多资料,结果没有找到答案的,我的问题如下:
我的主程序调用一个DLL(简称第一个DLL),这个第一个DLL中静态调用了其他的DLL(简称第二个DLL),在关闭第一个DLL时无法完全释放,从内存中可以看到还有残余的东东,代码如下,请教大家帮我。
第一个DLL(下含一个FORM,该FORM中调用了第二个DLL)
library P_wqfx;
uses
ShareMem,
ActiveX,
SysUtils,
Classes,
Forms,
windows,
RemoteUdpConnection,
RemoteStoredProc,
remoteudpdataset,
U_WQSZ in 'U_WQSZ.pas' {F_TZWQ};
{$R *.res}
PROCEDURE WQ_FX(H: THandle; app: TForm; AConn: TRemoteUdpConnection; lpid, yhjs: STRING); Stdcall;
VAR
frm: TF_TZWQ;
ptr: PLongInt;
i: integer;
BEGIN
Application.Handle := h;
ptr := @(application.MainForm);
ptr^ := longint(app);
frm := TF_TZWQ.Create(app);
FOR i := 0 TO frm.ComponentCount - 1 DO
BEGIN
IF frm.Components IS tremoteudpdataset THEN
(frm.Components AS tremoteudpdataset).remoteudpconnection := AConn;
END;
///////初始化窗体
frm.lpids := lpid;
frm.YHJS := yhjs;
frm.ShowModal;
FreeAndNil(frm);
END;
EXPORTS
WQ_FX;
VAR
DLLApp: TApplication;
DLLScreen: TScreen;
PROCEDURE DLLUnloadProc(Reason: Integer);
BEGIN
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp; //恢复
Screen := DLLScreen;
end;
END;
BEGIN
DLLApp := Application; //保存 DLL 中初始的 Application 对象
DLLProc := @DLLUnloadProc; //保证 DLL 卸载时恢复原来的 Application
DLLApp := Application; //保存 DLL 中初始的 Application 对象
DLLScreen := Screen;
DLLProc := @DLLUnloadProc; //保证 DLL 卸载时恢复原来的 Application
DLLUnloadProc(DLL_PROCESS_DETACH);
END.
主程序如下:
procedure Tfrm_hoho.Button32Click(Sender: TObject);
TYPE TWQ_FX= PROCEDURE(H: THandle; app: TForm; AConn: TRemoteUdpConnection; lpid, yhjs: STRING); Stdcall;
VAR
DLLHandle: THandle; //使用DLL句柄
FPointer: pointer; //定义函数入口指针
WQ_FX: TWQ_FX; //定义函数类型变量
BEGIN
DLLHandle := LoadLibrary('P_wqfx.dll'); //DLL文件的绝对路径
IF DLLHandle = 0 THEN //判断句柄是否有值
BEGIN
Application.MessageBox('加载错误_wqfx.dll', '提示', MB_OK +
MB_ICONSTOP);
Exit;
END;
IF DLLHandle > 0 THEN
TRY
FPointer := GetProcAddress(DLLHandle, 'WQ_FX'); //根据函数名称获得函数指针
IF FPointer <> NIL THEN //判断FPointer是否为空,不为空则得到函数地址
BEGIN
WQ_FX := TWQ_FX(FPointer); //指针强制转化为函数指针
WQ_FX(frm_hoho.Handle, frm_hoho, RemoteUdpConnection1, '8','1'); //调用导出的函数
END
ELSE
application.MessageBox(' WQ_FX调用出错', '错误', MB_OK + MB_IconError);
FINALLY
FreeLibrary(DLLHandle);
END;
end;
第一个DLL中采用的是静态调用DLL
//权限控制
PROCEDURE SORH(TF: tform; rds_temp, RDS_TEMP1: tremoteudpdataset; yhjsid: string); Stdcall;External 'P_procedure.dll';
//装载数据指令过程
PROCEDURE a_loaddata(remotedataset1, rds_temp: tremoteudpdataset; remoteupdatesql1: tremoteupdatesql; s_data, s_where: STRING); Stdcall;External 'P_procedure.dll';
我的主程序调用一个DLL(简称第一个DLL),这个第一个DLL中静态调用了其他的DLL(简称第二个DLL),在关闭第一个DLL时无法完全释放,从内存中可以看到还有残余的东东,代码如下,请教大家帮我。
第一个DLL(下含一个FORM,该FORM中调用了第二个DLL)
library P_wqfx;
uses
ShareMem,
ActiveX,
SysUtils,
Classes,
Forms,
windows,
RemoteUdpConnection,
RemoteStoredProc,
remoteudpdataset,
U_WQSZ in 'U_WQSZ.pas' {F_TZWQ};
{$R *.res}
PROCEDURE WQ_FX(H: THandle; app: TForm; AConn: TRemoteUdpConnection; lpid, yhjs: STRING); Stdcall;
VAR
frm: TF_TZWQ;
ptr: PLongInt;
i: integer;
BEGIN
Application.Handle := h;
ptr := @(application.MainForm);
ptr^ := longint(app);
frm := TF_TZWQ.Create(app);
FOR i := 0 TO frm.ComponentCount - 1 DO
BEGIN
IF frm.Components IS tremoteudpdataset THEN
(frm.Components AS tremoteudpdataset).remoteudpconnection := AConn;
END;
///////初始化窗体
frm.lpids := lpid;
frm.YHJS := yhjs;
frm.ShowModal;
FreeAndNil(frm);
END;
EXPORTS
WQ_FX;
VAR
DLLApp: TApplication;
DLLScreen: TScreen;
PROCEDURE DLLUnloadProc(Reason: Integer);
BEGIN
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp; //恢复
Screen := DLLScreen;
end;
END;
BEGIN
DLLApp := Application; //保存 DLL 中初始的 Application 对象
DLLProc := @DLLUnloadProc; //保证 DLL 卸载时恢复原来的 Application
DLLApp := Application; //保存 DLL 中初始的 Application 对象
DLLScreen := Screen;
DLLProc := @DLLUnloadProc; //保证 DLL 卸载时恢复原来的 Application
DLLUnloadProc(DLL_PROCESS_DETACH);
END.
主程序如下:
procedure Tfrm_hoho.Button32Click(Sender: TObject);
TYPE TWQ_FX= PROCEDURE(H: THandle; app: TForm; AConn: TRemoteUdpConnection; lpid, yhjs: STRING); Stdcall;
VAR
DLLHandle: THandle; //使用DLL句柄
FPointer: pointer; //定义函数入口指针
WQ_FX: TWQ_FX; //定义函数类型变量
BEGIN
DLLHandle := LoadLibrary('P_wqfx.dll'); //DLL文件的绝对路径
IF DLLHandle = 0 THEN //判断句柄是否有值
BEGIN
Application.MessageBox('加载错误_wqfx.dll', '提示', MB_OK +
MB_ICONSTOP);
Exit;
END;
IF DLLHandle > 0 THEN
TRY
FPointer := GetProcAddress(DLLHandle, 'WQ_FX'); //根据函数名称获得函数指针
IF FPointer <> NIL THEN //判断FPointer是否为空,不为空则得到函数地址
BEGIN
WQ_FX := TWQ_FX(FPointer); //指针强制转化为函数指针
WQ_FX(frm_hoho.Handle, frm_hoho, RemoteUdpConnection1, '8','1'); //调用导出的函数
END
ELSE
application.MessageBox(' WQ_FX调用出错', '错误', MB_OK + MB_IconError);
FINALLY
FreeLibrary(DLLHandle);
END;
end;
第一个DLL中采用的是静态调用DLL
//权限控制
PROCEDURE SORH(TF: tform; rds_temp, RDS_TEMP1: tremoteudpdataset; yhjsid: string); Stdcall;External 'P_procedure.dll';
//装载数据指令过程
PROCEDURE a_loaddata(remotedataset1, rds_temp: tremoteudpdataset; remoteupdatesql1: tremoteupdatesql; s_data, s_where: STRING); Stdcall;External 'P_procedure.dll';