Initialization/Finalization

Top  Previous  Next

What is translated > Statements > Initialization/Finalization

There is no direct counterpart for the initialization and finalization sections of a unit in C++. These sections are therefore translated as two functions containing the corresponding instructions.

 

Delphi2Cpp offers two methods to generate automatic calls to these functions. Sometimes the initialization of a unit requires that the initialization of another unit has already been done. In this case, the option to create a special file that will reproduce the Delphi initialization order must be selected. If there are no such dependencies, you can choose the option that initialization and finalization takes place automatically in each file.

 

 

1. Calling the initialzation/finalization procedures automatically per File

 

1. a) using an internal initialization-finalization class

 

If this option is chosen, a global variable of a class is written. The initialization routine is called in the constructor of this class and the finalization routine is called in the destructor. When the program starts, the global variables are first created and the units are also initialized. The following example is taken from SynEditHighlighter.pas:

 

 

initialization

  G_PlaceableHighlighters := TSynHighlighterList.Create;

finalization

  G_PlaceableHighlighters.Free;

  G_PlaceableHighlighters := nil;

 

->

 

void Init()

{

       G_PlaceableHighlighters = new TSynHighlighterList();

}

 

void Finalize()

{

       delete G_PlaceableHighlighters;

       G_PlaceableHighlighters = nullptr;

}

 

class SynEditHighlighter_unit

{

public:

       SynEditHighlighter_unit()

       {

               Init();

       }

       ~SynEditHighlighter_unit()

       {

               Finalize(); 

       }

};

 

SynEditHighlighter_unit _SynEditHighlighter_unit;

 

 

This however is only the short version.

 

 

1 b). Manual correction of nitialization-finalization calls:

 

 

If there are cases in which the initialization of a unit requires that of another unit, the code generated for option 1 can be improved manually. Therefore Delphi2Cpp already generates code that allows these corrections to be made easily. The declarations:There will be an additional static boolean variable, that prevents that the initialization or finalization is executed twice. E.g.:

 

 

static bool SynEditHighlighter_Initialized = false;

 

void SynEditHighlighter_initialization()

{

       if(SynEditHighlighter_Initialized)

               return;

       

       SynEditHighlighter_Initialized = true;

       

       G_PlaceableHighlighters = new TSynHighlighterList();

}

...

 

This allows the developer to easily call the corresponding functions from another file to enforce a specific order of initialization or finalization. A subsequent call by the constructor/destructor does no harm.

 

 

2. Using a Lifecycle Manager class

 

Alternatively, there is the option to have the order of the initialization-finalization calls controlled by an external initialization-finalization class. In this case, an additional file is generated that defines a class whose constructor calls all initialization procedures of the various units in the correct order and whose destructor ensures that the units are finalized accordingly.

 

The name of the control file is generated by appending "LCM" to the name of the Delphi2Cpp project option used for translation. The class name is further prefixed with a 'C'. For example, if the SynEdit.prj project options are used to translate the SynEdit components, the resulting control file name would be:

 

SyneditLCM.cpp / SyneditLCM.h

 

and the generated class is:

 

class CSyneditLifecycleManager {

public:

  CSyneditLifecycleManager()  {Syneditlcm::Synedit_init();}

  ~CSyneditLifecycleManager() {Syneditlcm::Synedit_exit();}

};

 

Synedit_init and Synedit_exit are two procedures that handle all the initialization and finalization routines for the units used in the project.

 

An instance of the CSyneditLifecycleManager class must be created within the main file:

 

CSyneditLifecycleManager _SyneditLifecycleManager;

 

This ensures that all initializations are performed before the main function starts, and all finalizations are executed afterward.

 

For classic C++Builder, the class does not need to be used. Instead, two pragmas automatically handle the calls to the initialization and finalization routines:

 

#pragma startup Synedit_init

#pragma exi Synedit_exit

 

The disadvantage of using Lifecycle Manager files is that if a file is used in different projects, a separate initialization-finalization file must be created for each one.



This page belongs to the Delphi2Cpp Documentation

Delphi2Cpp home  Content