January 2021 Nokia Solutions & Networks (Bangalore, India), accepted the offer for cooperation *). A program of a network software was translated from Delphi to C++ within the two-month support. The whole software consisted of several programs that shared a auxiliary code of approximately 1.2 MB. About the first half of the time was spent correcting the automatically translated code in order to compile and run the program. The rest of the time the program was debugged. In parallel DelphiXE2Cpp11 was improved with the knowledge gained.

Many nested routines are used in the code, and often also such routines that call themselves in their function body. Manual corrections had to be made for them. With the new update of DelphiXE2Cpp11, these are no longer necessary.

The software uses the compression libraries zlib and libbz2. By translating "System.ZLib", these libraries can now be seamlessly integrated into the translated code.

Post-processing is necessary at the positions where WINAPI commands or assembler code is executed. The conversion of the assembler code was carried out by the client.

Some critical special cases, which can not be automatically handled correctly during translation, are presented below.

"String*" and "TByte*" instead of simple Delphi "Pointer"

An own list class whose elements are derived from an abstract element class is of central importance in the Delphi software to be converted. In this element class there is both an abstract method that supplies a key of the Delphi "pointer" type and an abstract method for comparing these keys. The respective comparison functions do not compare the pointers themselves, but that, what they point to. Depending on the list element, these can be different integer types, but also strings or TBytes.
Here it turned out to be necessary not to save the contained pointers to the respective arrays, but to use a pointer to a String - string * - or a pointer to a TBytes - TBytes*. In the latter case in particular, the vector <Byte> container cannot be reconstructed from the vector<Byte>::data pointer. On the other hand, there are various records that can store different types in the variant part. Here, too, it was necessary to replace the abstract "pointer" type used in Delphi with the concrete types "String*" or TByte*".
The possibility of automatic translation comes to an end here. Of course, an automatic translator cannot recognize what a "pointer" actually stands for.

Construction of an object from a class reference where a parameter is passed

The second example for a necessary manual post-processing again concerns the already mentioned list container class and the hierarchy of the list elements. An element is created by the constructor of the container by calling the constructor method of a class reference of the element.

constructor TContainer.Create(S : ...; ObjectType : TElementClass);
i : Integer;

Items[i] := ObjectType.Create(S);

There are no such class references in C++. Due to the tricky auxiliary code for DelphiXE2Cpp11, it is only possible to simulate class references whose default constructor can be called.

Items[i] := ObjectType.Create();

In order to reproduce the Delphi code anyway, the part of the constructor code that depends on the passed parameter (in the current case a stream class) has to be extracted manually into a separate function. The element type is then generated by calling the default constructor and then initialization is carried out using the split-off function.

TElement* p = ObjectType->Create();

This splitting of the constructor must be carried out manually for all classes derived from the element class.

Calling a virtual class function within constructors

In the Delphi source code there is a hierarchy of classes with a virtual class function "Id", which returns an identifier that is specific to the respective class:

class function Id : string; virtual; abstract;

Depending on the identifier, certain code is now executed in the constructor of the base class. There are no virtual static methods in C++. Therefore, this method is translated as a simple virtual method. If a derived class is constructed, the constructor of the base class is also executed. In Delphi, the Id-function here delivers the identifier of the derived class. In C++, on the other hand, the identifier of the base class is delivered.

In this case, a supplementary constructor with the identifier as a parameter had to be written manually for the basic class.
In the constructor of the derived class, the new constructor of the base class is now called with the identifier of the derived class as a parameter.

TDerived(): inherited(Id()) {}

*) The offer for cooperation still exists, but now with reduced support time.

   deutsch Deutsch


Latest News
Delphi2Cpp: Delphi 10.3 inline variables [more...]

Delphi2CB: has been relased [more...]

"Thanks for your great work, really appreciate the work you have done on zlib and compiling ... test case."

Mattewada, Udayabhaskar
Nokia India 02/01/2021

[from case study...]

"A masterpiece -- Delphi2Cpp has exceeded all my expectations by far."

Tony Hürlimann
virtual-optima 08/20/2011

"First off, I have to say WOW! Delphi2Cpp is doing a *fantastic* job!"

Daniel Flower
linkrealms 01/15/2011

This website is generated from plain text with [Minimal Website ]

Minimal Website
Minimal Website is made with TextTransformer

TextTransformer is made with Borland CBuilder