Friday, October 26, 2007

DN4DP#26: .NET vs Win32: Initialization and finalization

This post continues the series of The Delphi Language Chapter teasers from Jon Shemitz’ .NET 2.0 for Delphi Programmers book.

Last time we looked at the .NET and Win32 casting issues. Here we quickly covers some potential gotchas related to initialization and finalization sections.

Note that I do not get any royalties from the book and I highly recommend that you get your own copy – for instance at Amazon.

 "Initialization and finalization

On the native Win32 platform, the Delphi unit initialization and finalization sections have exact (static) execution order and execution time semantics. On the .NET platform, the Delphi compiler implements initialization sections in terms of class constructors – this means that the order of execution is dependent on what types are used in what order at runtime. Likewise, running of an assembly’s unit finalization sections is triggered by a global object’s Finalize method – this implies that the code runs at an unspecified time on the CLR’s finalizer thread (and it is not always guaranteed to occur).

While most simple initialization and finalization code should work as is, you should be careful with code that relies on the execution order of these sections, code that touches types from other units and code that closes physical resources such as files. Old code that only frees memory in the finalization section can typically be IFDEFed out in .NET code.

unit InitializatonAndFinalizationU;

interface

type
TFoo = class
constructor Create;
end;

procedure Test;

implementation

uses
InitializatonAndFinalizationU2;

procedure Test;
begin

end;

{ TFoo }

constructor TFoo.Create;
begin
inherited Create;
writeln('TFoo.Create');
end;

initialization
TBar.Create;
writeln('InitializatonAndFinalizationU.initialization');

finalization
writeln('InitializatonAndFinalizationU.finalization');

end.
unit InitializatonAndFinalizationU2;

interface

type
TBar = class
constructor Create;
end;

procedure Test;

implementation

uses
InitializatonAndFinalizationU;

procedure Test;
begin

end;

{ TBar }

constructor TBar.Create;
begin
inherited Create;
writeln('TBar.Create');
end;

initialization
TFoo.Create;
writeln('InitializatonAndFinalizationU2.initialization');

finalization
writeln('InitializatonAndFinalizationU2.finalization');

end.
program InitializatonAndFinalization;

{$APPTYPE CONSOLE}

uses
SysUtils,
InitializatonAndFinalizationU in 'InitializatonAndFinalizationU.pas',
InitializatonAndFinalizationU2 in 'InitializatonAndFinalizationU2.pas';

begin
InitializatonAndFinalizationU.Test;
readln;
end.

No comments:

Post a Comment

Comments are moderated - spam and non-relevant links to will be deleted.