Finalization order in DLL

0 views
Skip to first unread message

Manoj Krishnan

unread,
Mar 11, 1999, 3:00:00 AM3/11/99
to
Hi

I have a Delphi 3 appln calling a Delphi 3 DLL. In the DLL, I create an
instance of a form and keep it so that I don't have to create it every time
I need to show the form.I don't explicitly free the form, instead I let the
Application object take care of freeing the form.
Now, when the EXE calls the (modal) form in the DLL and the user closes the
form and then the EXE, I get the ubiquitous 'Run time error 216' or 'Runtime
error 217'

Instead of using a DLL, if I integrate both the DLL and EXE into one single
executable, this error doesn't occur. After some debugging I found out that
in the EXE version, the form gets destroyed first and then only the
finalization section of all the units, but in the DLL version it is the
reverse. The finalization section of some of the units free some objects
which are later referred to when the Form is freed and this causes some
memory trashing.

So, my question is, how do I get the unit finalizations to be executed last
and secondly, is there any other reason for this?

TIA
Regards
Manoj

Stefan Hoffmeister

unread,
Mar 11, 1999, 3:00:00 AM3/11/99
to
: "Manoj Krishnan" <ma...@swi.com.sg> wrote:

>So, my question is, how do I get the unit finalizations to be executed last
>and secondly, is there any other reason for this?

Probably everything is going the right way. The trap you are proabably
falling into is the ownership of the form.

I *guess* that the form is owned by the application object inside the
DLL. This application object in the DLL and all its owned stuff is
destroyed VERY late indeed.

The application object in an EXE behaves slightly different: *before*
it is being destroyed and before the program shuts down at all (so
that the finalization sections are destroyed), all owned forms are
destroyed. Only then is the application object destroyed, then the
process is being terminated, then the finalization sections are
called.

If you make the form owned by the EXE's Application object then you
should see the appropriate behaviour. Or free it manually in the
finalization section of one of your DLL units.

--
Stefan Hoffmeister http://www.econos.de/
Due to time constraints I cannot give free face-to-face advice.
Please do apply judgement when sending email.

Steve Schafer (TeamB)

unread,
Mar 11, 1999, 3:00:00 AM3/11/99
to
On Thu, 11 Mar 1999 10:22:18 +0800, "Manoj Krishnan"
<ma...@swi.com.sg> wrote:

>So, my question is, how do I get the unit finalizations to be executed last

Load the DLL dynamically with LoadLibrary, and unload it explicitly,
in the OnClose or OnDestroy handler of your main form.

-Steve


Stefan Hoffmeister

unread,
Mar 11, 1999, 3:00:00 AM3/11/99
to
: "Manoj Krishnan" <ma...@swi.com.sg> wrote:

>Just a thought, is this behaviour put in by Borland/Inprise with a purpose
>or is it a feature ;-)

That's a feature of DLLs.

Manoj Krishnan

unread,
Mar 12, 1999, 3:00:00 AM3/12/99
to
Thank you Stefan - a different perspective on the same subject has done
wonders!!!

Stefan Hoffmeister wrote in message <36fcb671...@forums.inprise.com>...

>I *guess* that the form is owned by the application object inside the
>DLL. This application object in the DLL and all its owned stuff is
>destroyed VERY late indeed.

>If you make the form owned by the EXE's Application object then you


>should see the appropriate behaviour. Or free it manually in the
>finalization section of one of your DLL units.

Yes, you are right, the form is owned by the application object. In the EXE
version, I could be lazy and not free my form and let the Application object
do the freeing, but not so for the DLL version. I am now freeing the form in
the finalization. Though I do have to be careful as the same code is being
called by other EXEs and am setting the form variable to nil in its
OnDestroy event so that it won't be freed twice. ( see below )

At first blush, this seems to work fine, but it needs thorough testing, for
my 'Runtime error 216' would appear in about 50% of the cases!!

Just a thought, is this behaviour put in by Borland/Inprise with a purpose
or is it a feature ;-)

eg.

unit VisitSelect;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms ......
implementation
var
VisitSelectForm : TVisitSelectForm;

.......

procedure TVisitSelectForm.FormDestroy(Sender: TObject);
begin
VisitSelectForm := nil;
end;

initialization
VisitSelectForm := nil;
finalization
{free objects}
VisitSelectForm.Free;
VisitSelectForm := nil;
end.

Manoj Krishnan

unread,
Mar 12, 1999, 3:00:00 AM3/12/99
to
Steve Schafer (TeamB) wrote in message <36f1f5f1...@90.0.0.40>...

>Load the DLL dynamically with LoadLibrary, and unload it explicitly,
>in the OnClose or OnDestroy handler of your main form.

Yes, I am doing this...

Thanks


Reply all
Reply to author
Forward
0 new messages