Initialization/Finalization |
Top Previous Next |
What is translated > Statements > Initialization/Finalization There isn't any direct counterpart for the sections initialization and finalization of a unit in C++. These sections are therefore translated as two functions which contain the respective instructions. For a unit called Test, this would be:
void Tests_initialization(); void Tests_finalization();
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 SynEditHighlighter_initialization() { G_PlaceableHighlighters = new TSynHighlighterList(); }
void SynEditHighlighter_finalization() { delete G_PlaceableHighlighters; G_PlaceableHighlighters = nullptr; }
class SynEditHighlighter_unit { public: SynEditHighlighter_unit() { SynEditHighlighter_initialization(); } ~SynEditHighlighter_unit() { SynEditHighlighter_finalization(); } };
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 an external initialization-finalization 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 formed by appending the "_initexit" to the name of the Delphi2Cpp project option used for translation. The class name additionally is preceded by a 'C'. For example, the SynEdit.prj project options are used to translate the SynEdit components. The name of the control file then is:
Synedit_initexit.cpp / Synedit_initexit.h
and the generated class is:
class CSynedit_initexit { public: CSynedit_initexit() {Synedit_init();} ~CSynedit_initexit() {Synedit_exit();} };
Synedit_init and Synedit_exit are two procedures in which all initialization and finalization procedures of the units used in the project are called.
An instance of the CSynedit_initexit class has to be created inside of the main file.
CSynedit_initexit _Synedit_initexit;
Then all initializations and finalization are executed, before the main function starts.
For the classic C++Builder the class has not to be used. Two pragmas take care for the calls to the initialization and finalization routines instead:
#pragma startup Synedit_init #pragma exi Synedit_exit
The disadvantage of using initialization finalization files is that if a file is used in different projects, a separate initialization finalization file must be created for each one. For example, there are various demo applications for the Synedit components, each of which only requires some of the units. However, the Synedit components form a special stroke of luck. The SynEditHighlighter unit must be initialized before all special highlighters, but only if the components are to be registered. This is not necessary for the demo applications. The use of the initialization-finalization class without instantiation prevents conflicting initialization from occurring at all.
|
This page belongs to the Delphi2Cpp Documentation |
Delphi2Cpp home Content |