求助,我作一Dll程序其中有一Form但调用后不能正常释放Dll ( 积分: 100 )

  • 主题发起人 主题发起人 pu-tian
  • 开始时间 开始时间
P

pu-tian

Unregistered / Unconfirmed
GUEST, unregistred user!
主工程
program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
主单员文件
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
type
tfun=function(app:TApplication):TForm;
var
f:tfun;
h:HWND;
frm:tform;
begin
h:=loadlibrary(pchar('Project2.dll'));
@F:=GetProcAddress(h,'CF');
frm:=f(Application);
frm.Show;
end;

end.
////////////////////////////////////////////////////////////////////////////
///Dll工程文件
////////////////////////////////////////////////////////////////////////////
Library Project2;

uses
Forms,
Windows,
SysUtils,
Messages,
Classes,
Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

var
DLLApp: TApplication;

function CF(App: TApplication):TForm;
begin
Application := App;
Application.CreateForm(TForm2, Form2);
result:=Form2;
end;

procedure ExitDLL(reason:Integer);
begin
if Reason = DLL_PROCESS_ATTACH then
begin
Application := DLLApp;
end;
end;

exports
CF;

begin
DLLApp := Application;
DLLProc := @ExitDLL;
end.
//////////////////////////////////////////////////////////////////////////
//Dll单元文件
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus;

type
TForm2 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

end.
 
主工程
program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
主单员文件
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
type
tfun=function(app:TApplication):TForm;
var
f:tfun;
h:HWND;
frm:tform;
begin
h:=loadlibrary(pchar('Project2.dll'));
@F:=GetProcAddress(h,'CF');
frm:=f(Application);
frm.Show;
end;

end.
////////////////////////////////////////////////////////////////////////////
///Dll工程文件
////////////////////////////////////////////////////////////////////////////
Library Project2;

uses
Forms,
Windows,
SysUtils,
Messages,
Classes,
Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

var
DLLApp: TApplication;

function CF(App: TApplication):TForm;
begin
Application := App;
Application.CreateForm(TForm2, Form2);
result:=Form2;
end;

procedure ExitDLL(reason:Integer);
begin
if Reason = DLL_PROCESS_ATTACH then
begin
Application := DLLApp;
end;
end;

exports
CF;

begin
DLLApp := Application;
DLLProc := @ExitDLL;
end.
//////////////////////////////////////////////////////////////////////////
//Dll单元文件
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus;

type
TForm2 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

end.
 
窗体释放:FreeAndNil();
dll释放:FreeLibrary();
 
FreeLibrary后主窗体也就没有了,很奇怪,
而且Dll中的退出过程也没有执行
我在网上找过资料,都是这样写,他们说能运行,从DelphiFans里找到例子也是这样子,正常,不报错,感到很郁闷
 
我试了没问题啊,是哪里有问题,你的FreeLibrary是在哪里调用的
 
事實上你這個DLL是沒有完全釋放的,就算你用FreeLibrary();在進程裡有資源占用。
因為你的DLL裡FORM2還沒有釋放,如果用Form2.Free; Form2:=Nil; FreeAndNil(Form2);來釋放DLL裡的FORM2,然後你就會發現FreeLibrary();報錯。這是一個問題。
還有一個問題就是,當DLL放到EXE程序裡調用時,像子窗體一樣使用自由時,但一些沒有必要資源被占用,當釋放時就有更多報錯信息。
對於DLL方面我花了一個月來時間,查了近百個實例也沒有一個可行的方案。
我正想不知微軟是怎麼處理這個問題的?
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

//PROCEDURE setCNN(cnn:STRING); stdcall; external 'pws.dll';
FUNCTION ClockFrmCreate:boolean; stdcall; external 'vFrm.dll';


implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ClockFrmCreate;
end;

end.

library vFrm;

{ 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,
Classes,
Controls,
frm_ClockUnit in 'frm_ClockUnit.pas' {ClockFrm};

VAR
myCnn :STRING;
{$R *.res}

FUNCTION ClockFrmCreate:boolean; STDCALL;
VAR
ClockFrm:TClockFrm;
BEGIN

ClockFrm :=TClockFrm.Create(nil);
ClockFrm.Show;
result:=true;
END;

PROCEDURE setCNN(cnn:STRING); STDCALL;
BEGIN
//myCnn := cnn;
END;

EXPORTS
ClockFrmCreate;
BEGIN

END.
 
DLL中的窗体应最好由DLL创建,由DLL释放,
如果你在外部释放它,搞不好就会出个内存异常。
例子!就引用个别人的吧:
http://www.delphibbs.com/keylife/iblog_show.asp?xid=19232
 
同意楼上
 
问题已经解决了,如果谁想交流一下可以QQ我:12933881,说明原因
 

Similar threads

后退
顶部