Announcement

Collapse
No announcement yet.

Quelltext-Konvertierung delphi -> C#

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Quelltext-Konvertierung delphi -> C#

    Hallo an alle,

    wir haben vor, unsere 400.000 Zeilen Delphi-Quelltext nach C# zu konvertieren!

    Dabei helfen uns vor allem das Tool Netcoole Delphi2CS und das Buch ".NET 2.0 for Delphi Programmers" von Jon Shemitz.

    Wer auch immer zur Zeit in einer ähnlichen Situation ist, bitte bei mir melden. Tipps und Tricks sind willkommen.

    Auch ich habe inzwischen einige Erfahrung zu diesem Thema, so dass ich Umsteigern auch die eine oder andere Frage beantworten kann.

    Wolfgang

  • #2
    Nachtrag Netcoole - Turnsharp

    Noch ein Nachtrag:

    Da man ja besser vorsichtig formulieren muss, würde ich sagen: Das Delphi-C#-Konvertiertool Turnsharp ist ein preiswertes Tool, das sicherlich zu irgendwas gut ist, zur Konvertierung von Quelltext aber eher weniger.

    Sollte jemand ein Alternativ-Tool zu Netcoole Delphi2CS kennen, bitte melden!

    Comment


    • #3
      Welche Erfahrung hast Du denn mit Delphi2CS gemacht ?

      Comment


      • #4
        Mein Erfahrungsschatz zu Netcoole Delphi2CS

        Delphi2CS ist ein brauchbares Tool, um Delphi-Quelltexte zu konvertieren!

        Besonders beeindruckend finde ich dabei:

        1. Über das gesamte Projekt hinweg werden alle Namen auf Groß- und Kleinschreibung angepasst, damit C# keine Probleme damit hat. Aus diesem Grund ist es sinnvoll, für die Konvertierung alle zusammengehörigen DLLs und Packages in einem Projekt zusammenzufassen.

        2. Alle selbst geschriebenen Klassenstrukturen, Records, Interfaces, Enumerators werden 100% richtig nach C# übertragen. Hier ist keinerlei Nacharbeit nötig! (Achtung: Das gilt nicht für abgeleitete VCL-Objekte! S.u.)

        3. Bitmap-Operationen werden korrekt konvertiert.


        Nacharbeit erfordert alles, was auf Delphi-Bibliotheken zugreift:

        1. Oberflächen werden einigermaßen korrekt übertragen. Meistens muß man einparr bestimmte Eigenschaften korrigieren, dann kann Fenster in C# dargestellt werden. Oft sind es immer die gleichen Dinge! Z.B.
        xControl.Align := alClient;
        muss immer manuell in
        xControl.Dock = DockStyle.Fill;
        geändert werden.

        2. TabControl: Zu TTabControl gibt es kein Pendant in Winforms!! TPageControl ist OK!

        3. TStringList wird immer als System.Collections.Specialized.StringDictionary übersetzt. Dieses Objekt ist aber viel zu mächtig und umständlich. In 99% der Fälle sollte StringDictionary durch System.Collections.Generic.List<string> oder einfach string[] ersetzt werden.


        Sonstige Nacharbeiten:

        1. Bei mehereren Konstruktoren macht der Konvertierer immer den gleichen Fehler: Er schriebt nicht :base(x,y,z), sondern :this(x,y,z). Einfach this in base ändern, fertig!

        2. C# nimmt es übel, wenn eine abgeleitete Klasse keinen Konstruktor und die basisklasse eine K. mit mehreren Params hat. Dann muß man einen leeren Konstruktor definieren

        3. Free-Aufrufe werden nicht konvertiert, weil in C# die GarbageCollection dafür zuständig ist. Man kann eigentlich alle Free-Aufrufe löschen. Destruktoren, die nur Free-Aufrufe enthalten, kann man auch löschen. try-finally-Blöcke mit der einzigen Aufgabe, Free aufzurufen, auch.

        4. Ein "billiges overload" mit procedure XY( a: boolean = false) ist in C# unbekannt. Dort müssen alle Möglichkeiten einzeln als überladene Funktionen nachgetragen werden.


        Wichtig ist, dass einem die Unterschiede zwischen Delphi und C# klar sind, dann kann man bereits in Delphi bestimmte Konstukte vermeiden, die einem die Konvertierung versauen:

        1. Niemals selber VCL-Objekte ableiten. Das kann nicht konvertiert werden.

        2. Mehr drauf achten, ob ein Parameter out oder var ist. Im Zweifelsfall immer out!!! Der C#-Compiler läßt es nicht durchgehen, wenn ein ref(var)-Parameter nicht initialisiert ist.

        3. Integer-Typen werden nicht automatisch ineinander konvertiert. Das kostet viel Zeit bei der Nachbearbeitung. Am besten immer nur "integer" benutzen! ShortInt, Word, Cardinal und ähnlichen Quatsch sollte man nur dann verwenden, wenn es zwingend notwendig ist.

        4. Pro Klasse darf es nur eine indizierte property geben. Diese sollte man bereits in Delphi als "default;" kennzeichnen und ohne Bezeichner verwenden.

        5. TQuery, TTable, TIniFile machen viel Ärger bei der Konvertierung. Am besten, man reduziert Zugriffe auf diese Objekte durch Kapselung.


        Was wirklich nervt und viel Zeit kostet:

        1. Für viel Spaß sorgt folgender Unterschied: Bei Delphi hat der erste Buchstabe eines strings den Index 1, bei C# den Index 0. Leider wird dieser Umstand von Delphi2CS nicht berücksichtigt. Also: alle string-Operationen prüfen!

        2. Die Funktion SysUtils.Format() wird nicht konvertiert. Alle Aufrufe dieser Funktion müssen von Hand konvertiert werden.

        3. ref und out müssen in C# auch in die aufrufendene Funktion geschrieben werden. Das tut das Programm leider nicht (Ich hoffe auf die nächste Version).

        -------------------------------

        Das soll erst mal reichen. Wenn jemand mehr wissen will, kann ich noch mehr berichten.

        Comment


        • #5
          Danke noch einmal für den Erfahrungsbericht

          Comment


          • #6
            Delphi2Cs

            Hallo!

            Ich beschäftige mich auch grad mit dem Thema und möchte meine Delphi Projekte in C# konvertieren.

            Ist die im Laufe der Zeit noch etwas wichtiges aufgefallen bzw. hast du ein anderes Tool gefunden, womit die Konvertierung noch besser geht bzw. Delphi2CS unterstützen könnte? Wie siehts eigentlich mit Datenbank-Verbindungen aus?

            Herzlichen Dank schon mal und

            lg

            Peter

            Comment


            • #7
              Hallo Peter,

              unabhängig davon, was die Erfahrungen mit Konvertierungs-Tools zeigen, muss ich Dich warnen: Der DB-Zugang ist unter NET komplett anders geregelt als unter Delphi. Beispielsweise wird eine DbConnection immer nur kurzfristig für einen Vorgang erstellt, geöffnet und sofort wieder geschlossen und gelöscht; dazu wird sie am besten in einen using-Block gekapselt. Ich kann mir nicht vorstellen, wie ein Datenmodul mit permanenter Connection in eine solche Klasse konvertiert werden kann.

              Gehe deshalb lieber davon aus, dass alle DB-Zugriffe manuell neu programmiert werden müssen. Jürgen

              Comment


              • #8
                DB - Connections

                Hallo!

                Schade, aber danke für die Info!

                Ich habe mir inzwischen selber ein eigenes Tool geschrieben, dass kleinere Änderungen* macht und ich nach Delphi2CS drüber laufen lasse.

                * Änderungen:

                - .Color = 094304; -> .Color = System.Drawing.Color.FromArgb(094304);
                - systemtime -> DateTime
                - GetWindowsDir -> Environment.GetEnvironmentVariable("windir", EnvironmentVariableTarget.Machine)
                - SW_SHOWNORMAL -> (ushort)System.Diagnostics.ProcessWindowStyle.Norm al
                - Font.Color -> ForeColor
                - Application.Terminate -> Application.Exit()


                Bin derzeit dabei, meine Library ständig zu erweitern, damit das Tool sinnvoll eingesetzt werden. Derzeit bin ich schon recht zufrieden -> Alleine die Eigenschaft ".Color = 094304" hätte ich dutzende Male nachziehen müssen, was ich mir mit meinem Tool erspart habe.

                Falls jemand weitere Änderungen weiß, welche nicht durch Delphi2CS abgedeckt werden, würde ich mich über ein Nahrung für meine Library freuen. Wenn ich wieder mehr Einträge habe, dann poste ich weitere Details (wenn gewünscht)

                lg

                Peter

                Comment


                • #9
                  Hallo,

                  für den Datenbankzugriff haben wir eine Wrapper-Klasse geschrieben, die die TQuery-Klasse kapselt. Die Implementierung in C# ist zwar komplett anders, aber alle Methoden, die den Wrapper benutzen, werden korrekt übersetzt.

                  Oberflächen, die auf Datenbank-Objekte zugreifen, sollte man am besten komplett neu schreiben, da lohnt der Übersetzungsaufwand nicht!

                  Für alle, denen systematische Fehler wie z.B. .Color = 094304 -> .Color = System.Drawing.Color.FromArgb(094304) auffallen: Scheut Euch nicht, diese Erkenntnisse an Netcoole zu schreiben! Pan von Netcoole freut sich immer sehr, wenn einem solche Dinge auffallen, und versucht, sie innerhalb weniger Tage zu fixen.

                  Gruß

                  Comment


                  • #10
                    Hallo Peter,
                    genial wäre, wenn Dein Tool Formatstrings korrekt übersetzen könnte! (Das will Pan von Netcoole nämlich nicht.)
                    Ich meine damit z.B. wenn Dein Tool den Ausdruck
                    SysUtils.Format('Plate: %s, Width %.2f mm', [Name, Width] );
                    übersetzen könnte in
                    string.Format( "Plate: {0}, Width {1:F2} mm", Name, Width );

                    Gruß
                    Wolfgang

                    Comment

                    Working...
                    X