Dll释放问题

coeltdit 2005-01-15 02:31:26
主窗体:
unit Main

interface
type
TBaseDllShowChild = procedure(ParentApplication: TApplication;ParentForm: TForm;FormName: string; FHanlde: Hwnd); stdcall;

EDllLoadError = class(Exception);

TFrmMain = class(TfrmComMain)
---------------------
---------------------
procedure TFrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
procedure BaseDllShowForm(Sender: TObject;FormName: string; DllName:String);
end;

procedure TFrmMain.BaseDllShowForm(Sender: TObject; FormName,
DllName: String);
var
BaseDllShowChild: TBaseDllShowChild;
begin
BeginShow(Sender);
if BaseDllHandle = 0 then
BaseDllHandle := LoadLibrary(PChar(DllName+'.Dll'));
if BaseDllHandle = 0 then
Raise EDllLoadError.Create('装载动态链接库'+DllName+'.Dll'+'失败!');
@BaseDllShowChild := GetProcAddress(BaseDllHandle,'BaseDllShowChild');
if @BaseDllShowChild <> nil then
BaseDllShowChild(Application,Self,FormName,Application.Handle)
else
RaiseLastWin32Error;
EndShow(Sender);
end;

procedure TFrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
inherited;
if BaseDllHandle <> 0 then
begin
FreeLibrary(BaseDllHandle);
BaseDllHandle := 0;
end;
Action :=caFree;
end;

Dll:
procedure BaseDllShowChild(ParentApplication: TApplication; ParentForm: TForm;FormName:String;FHandle:Hwnd); export; stdcall;
begin
Application.Handle := FHandle;
Application:=ParentApplication;
FormName := UpperCase(FormName);
if FormName='FRMHRRANK' then
begin
if not Assigned(frmHrRank) then
frmHrRank := TfrmHrRank.Create(ParentForm);
frmHrRank.Show;
end;
end;

procedure DLLUnloadProc(Reason: Integer); register;
begin
if Reason = DLL_PROCESS_DETACH then
Data.Free;
end;

exports
BaseDllShowChild;

begin
DllName := 'BaseDll';
if not Assigned(Data) then
Data := TData.Create(Application);
DLLProc := @DLLUnloadProc;
end.
----------------------------------------------------------------------------------------
程序采用MDI窗体,能够正常调用DLL中的窗体,但关闭主程序后DLL不能正常释放,还在任务管理器占用11M的内存;请帮忙解决!
...全文
259 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
coeltdit 2005-01-18
  • 打赏
  • 举报
回复
顺便问一下,DELPHI生成的扩展名为MPS,MPT是啥文件? 有啥作用?
回答完这个问题马上结贴!
coeltdit 2005-01-18
  • 打赏
  • 举报
回复
to dickeybird888:
我是WINRAR压缩的,不可能打不开啊?
不过现在问题已经解决了, 谢谢所有答复我问题的朋友!
dickeybird888 2005-01-18
  • 打赏
  • 举报
回复
有问题的话,在告诉我把
dickeybird888 2005-01-18
  • 打赏
  • 举报
回复
老大,你给我发的什么文件啊!怎么打不开啊!我用winrar打不开啊
coeltdit 2005-01-17
  • 打赏
  • 举报
回复
to dickeybird888(于伟刚) :
照你说的做了,还是不行, 邮件已发送,请查收, 感谢!
jack_zhong 2005-01-17
  • 打赏
  • 举报
回复
不过有谁能帮我解答一下
http://community.csdn.net/Expert/topic/3730/3730427.xml?temp=.5554621
里的问题,我想结贴啊
jack_zhong 2005-01-17
  • 打赏
  • 举报
回复
这是我的一个DLL的程序:
library P_Work_Plan;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
SysUtils,
Forms,
Classes,
inifiles,
Windows,
Messages,
work_in in 'WORK_IN.PAS' {Work},
query1 in 'QUERY1.PAS' {Form2},
ShipQuery in 'ShipQuery.pas' {ship_query},
data in 'DATA.PAS' {M_Data: TDataModule},
CaInvoice in 'CaInvoice.pas' {NewInvoice};

{$R *.res}

var
DLLApp: TApplication;
DLLScr: TScreen;


function CreateWorkForm(App: TApplication; Scr: TScreen):TForm;
var
ptr:PLongInt;
begin
Application := App;
Screen := Scr;
Application.CreateForm(Twork, work);
//Application.CreateForm(TNewInvoice, NewInvoice);
//Application.CreateForm(TM_Data, M_Data);
result:=work;
end;

function CreateShopInfoForm(App: TApplication; Scr: TScreen):TForm;
var
ptr:PLongInt;
begin
Application := App;
Screen := Scr;
Application.CreateForm(Tship_query, ship_query);
//Application.CreateForm(TM_Data, M_Data);
result:=ship_query;
end;

procedure ExitDLL(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScr;
end;
end;

exports
CreateWorkForm,CreateShopInfoForm;

begin
DLLApp := Application;
DLLScr := Screen;
DLLProc := @ExitDLL;

end.
主程序的调用:
procedure TMDI.dxBarButton60Click(Sender: TObject);
begin
//船期预报查询
if DLLHandle <> 0 then
begin
@DLLSub := GetProcAddress(DLLHandle, 'CreateShopInfoForm');
if Assigned(DLLSub) then
begin
DLLForm := DLLSub(Application, Screen);
end;
end;
end;
dickeybird888 2005-01-17
  • 打赏
  • 举报
回复
如果还是不行的话把程序发给我把,我给你改改:
dickeybird888@yahoo.com.cn
dickeybird888 2005-01-17
  • 打赏
  • 举报
回复
Exports
BaseDllShowChild;

Var DllApplication:TApplication;
DllScreen:TScreen;

{$R *.RES}

procedure LibraryProc(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Screen:=DllScreen;
Application:=DllApplication;
end;
end;

begin
DllApplication:=Application;
DllScreen:=Screen;
DLLProc:=@LibraryProc;
end.
coeltdit 2005-01-17
  • 打赏
  • 举报
回复
to Kshape:
加Exit后可以完全释放DLL,但单步调试到Exit就会报读址错误, 编译以后基本上可以正常运行,偶尔也会报读址错误, 请帮忙再看看;
coeltdit 2005-01-17
  • 打赏
  • 举报
回复
to dickeybird888:
照你的建议做了也不行,请再帮忙看看!
-------------------------------------------------------------------------------------
procedure DLLUnloadProc(Reason: Integer); register;
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := JbzlApplication; //Application.Handle归还给HostExe
Screen := JbzlScreen;
Data.Free;
end;
end;

exports
BaseDllShowChild;

begin
JbzlApplication := Application;
JbzlScreen := Screen;
DllName := 'BaseDll';
if not Assigned(Data) then
Data := TData.Create(Application);
DLLProc := @DLLUnloadProc;
end.
Kshape 2005-01-16
  • 打赏
  • 举报
回复
我以前也是这样,用动态链接库就出问题
郁闷
个人觉得
--------------------------------------
procedure TFrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
inherited;
if BaseDllHandle <> 0 then
begin
FreeLibrary(BaseDllHandle);
BaseDllHandle := 0;
exit;//加上这句话看看行吗?
end;
Action :=caFree;
end;
-----------------------
上面代码很可能有问题
cyf_delphi 2005-01-16
  • 打赏
  • 举报
回复
关注
学习
dickeybird888 2005-01-16
  • 打赏
  • 举报
回复
你只注意到了第一个,而没有注意到第二个
dickeybird888 2005-01-16
  • 打赏
  • 举报
回复
采用MDI的时候要注意两个要素:
1.application.handle
2.screen
coeltdit 2005-01-15
  • 打赏
  • 举报
回复
现在看起来很严重,在Win2000系统中经常在主程序退出时,电脑发出嘟嘟声, 然后接着蓝屏, 并提示内存错误, BaseDll是考勤系统中的基本资料模块,采用是的MDI多文档窗口.
请大家帮帮忙, 列出各种可能引起这种异常的原因,先谢了!

coeltdit 2005-01-15
  • 打赏
  • 举报
回复
to aiirii:
我主程序退出时已经调用FreeLibrary(BaseDllHandle)了,为什么还要定义并调用一个BaseDllFree类?给个理由。
aiirii 2005-01-15
  • 打赏
  • 举报
回复
我以前做的, 主程序在退出是時, 還要調用一個 BaseDllFree 類的來主動釋放 dll 中和資源
coeltdit 2005-01-15
  • 打赏
  • 举报
回复
procedure DLLUnloadProc(Reason: Integer); register;
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := JbzlApplication; //Application.Handle归还给HostExe
Data.Free;
end;
end;

exports
BaseDllShowChild;

begin
JbzlApplication := Application;
DllName := 'BaseDll';
if not Assigned(Data) then
Data := TData.Create(Application);
DLLProc := @DLLUnloadProc;
end.
-----------------------------------------------------------------------------------
to largewang:
不行的,我一开始就加上去了,是没有粘贴上去,请再帮忙看看。
largewang 2005-01-15
  • 打赏
  • 举报
回复
请把Application.Handle归还给HostExe

在procedure DLLUnloadProc(Reason: Integer); register;中处理
加载更多回复(2)

2,496

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧