Konvertieren von 32-Bit-Delphi-Anwendungen in 64-Bit-Windows

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu 64-Bit-Windows-Anwendungsentwicklung


Wenn Sie eine Codebasis mit 32-Bit-Windows-Delphi-Anwendungen nach 64-Bit-Windows konvertieren möchten, sollten Sie

  • Die 32-Bit-Anwendung in der IDE öffnen, die 64-Bit-Windows-Zielplattform hinzufügen und die Anwendung als 64-Bit-Windows-Anwendung compilieren. (Einzelheiten dazu finden Sie unter Schritte bei der Entwicklung von geräteübergreifenden Anwendungen.)
  • Die folgenden Punkte überprüfen und ggf. anpassen (beziehen sich hauptsächlich auf Zeigeroperationen, NativeInt-Größe und Assembly-Code).

Zeigeroperationen

Sie sollten Zeigeroperationen in Ihrer Codebasis überprüfen.

  • Die Größer aller Zeiger wurde folgendermaßen geändert:
    • Auf einer 32-Bit-Windows-Plattform ist ein Zeiger 4 Byte groß.
    • Auf einer 64-Bit-Windows-Plattform ist ein Zeiger 8 Byte groß.
  • Sie können von Folgendem ausgehen:
    SizeOf(Pointer)=SizeOf(Integer/Cardinal/Longint)
  • Beachten Sie beim Inkrementieren von Zeigern, dass das Verhalten eines 64-Bit-Zeigers nicht identisch mit dem eines 32-Bit-Zeigers sein kann. Sie müssen ggf. Anpassungen in Ihrem Code vornehmen.
    • Richtig:
    MyPtr := PByte(P) + 10;
    • Abwärtskompatibel:
    MyPtr := PAnsiChar(P) + 10;
    • Falsch:
    MyPtr := Pointer(Integer(P) + 10);
  • Sie können von Folgendem ausgehen:
    SizeOf(Pointer) == 4
    • Richtig:
    Move(FSelection[Index + 1], FSelection[Index], (FSelectionCount - Index - 1) * SizeOf(Pointer));
    • Falsch:
    Move(FSelection[Index + 1], FSelection[Index], (FSelectionCount - Index - 1) * 4);

Weitere Informationen über die Verwendung von Zeigern in 64-Bit-Windows-Anwendungen finden Sie in dem MSDN-Artikel Rules for Using Pointers.

Integer-Typen

  • Auf einer 64-Bit-Windows-Plattform bleiben Integerwerte 4 Byte groß.

Die Größe von NativeInt ändert sich

  • Auf der 64-Bit-Windows-Plattform beträgt die Größe von NativeInt jetzt 8 Byte.
  • Auf der 32-Bit-Windows-Plattform beträgt die Größe von NativeInt weiterhin 4 Byte.


Inline-Assembly-Code

Wenn Ihre Anwendung ASM-Code (Inline Assembly) enthält, müssen Sie den ASM-Code überprüfen und die folgenden Änderungen vornehmen:

  • In 64-Bit-Anwendungen wird das Mischen von Assembly-Anweisungen mit Pascal-Code nicht unterstützt. Ersetzen Sie Assembly-Anweisungen entweder durch Pascal-Code oder durch vollständig in Assembly geschriebene Funktionen.
  • Das Portieren von IA-32 nach Intel 64 kann nicht einfach durch Kopieren des Codes erfolgen. Bedenken Sie die Architektur-Spezifika, wie etwa die Größe von Zeigern und die Ausrichtung. Suchen Sie ggf. im Prozessor-Handbuch nach neuen Anweisungen. Verwenden Sie zum Compilieren desselben Codes für unterschiedliche Architekturen konditionale Definitionen. Siehe Verwenden von konditionalen Definitionen für plattformübergreifenden Code in "Verwendung des integrierten Assemblers".

RAD Studio unterstützt Intel x86 über SSE4.2 und AMD 3dNow und bei x64 Intel/AMD über SSE4.2.

Weitere Informationen finden Sie unter:

WinAPI-Aspekte

  • Wenn Sie Zeiger an SendMessage/PostMessage/TControl.Perform übergeben, sollten die Parameter wParam und lParam in den Typ WPARAM/LPARAM und nicht in Integer/Longint umgewandelt werden.
    • Richtig:
      SendMessage(hWnd, WM_SETTEXT, 0, LPARAM(@MyCharArray));
    • Falsch:
      SendMessage(hWnd, WM_SETTEXT, 0, Integer(@MyCharArray));
  • Ersetzen Sie SetWindowLong/GetWindowLog durch SetWindowLongPtr/GetWindowLongPtr für GWLP_HINSTANCE, GWLP_ID, GWLP_USERDATA, GWLP_HWNDPARENT und GWLP_WNDPROC, da sie Zeiger und Handles zurückgeben. Zeiger, die an SetWindowLongPtr übergeben werden, sollten in den Typ LONG_PTR und nicht in Integer/Longint umgewandelt werden.
    • Richtig:
      SetWindowLongPtr(hWnd, GWLP_WNDPROC, LONG_PTR(@MyWindowProc));
    • Falsch:
      SetWindowLong(hWnd, GWL_WNDPROC, Longint(@MyWindowProc));
  • Zeiger, die dem Feld TMessage.Result zugewiesen werden, sollten in den Typ LRESULT anstatt in Integer/Longint umgewandelt werden.
    • Richtig:
      Message.Result := LRESULT(Self);
    • Falsch:
      Message.Result := Integer(Self);
  • Alle TWM...-Records für die Behandlungsroutinen von Fensterbotschaften müssen die korrekten Windows-Typen für die Felder verwenden:
    Msg: UINT; wParam: WPARAM; lParam: LPARAM; Result: LRESULT)

Datenfeldausrichtung bei Record-Typen

In früheren Versionen von Delphi wurde die korrekte Datenausrichtung beim Aufruf von externen Bibliotheken und insbesondere von bestimmten externen Windows-API-Funktionen, für die record- oder struct-Parameter erforderlich waren, mit packed record sichergestellt. Nicht verwendete Datenfelder wurden "aufgefüllt", damit die erforderlichen Datenfelder wie benötigt ausgerichtet werden konnten. Die aktuelle Compiler-Implementierung macht eine derartige Verwendung von packed Records in den meisten Fällen überflüssig. Durch Überarbeitung von vorhandenem Quellcode und Entfernung von nutzlosen packed Records und "Auffüllungen" wird der Quellcode klarer und einfacher zu warten.

Wenn Ihre vorhandenen Datendateien kompatibel mit älteren Versionen von Delphi bleiben sollen, geben Sie die Compiler-Direktive {$OLDTYPELAYOUT ON} für Quellcode an, dessen alte Record-Organisation weiterhin benötigt wird.

Sonstige zu beachtende Aspekte

  • Die Prozedur DataEvent in der VCL-RTL ist von der Größenänderung von NativeInt betroffen.
Es wird evtl. ein Compiler-Fehler für virtuelle Methoden bezüglich des Überschreibens ausgegeben (E2170: Eine nicht-virtuelle Methode kann nicht überschrieben werden). In diesem Fall sind Codeänderungen erforderlich.
  • Das Funktions-Patching zur Laufzeit, wie z.B. das Einfügen einer nicht bedingten Sprunganweisung zur Umleitung einer Funktion, muss als 64-Bit-Anweisung umgeschrieben werden.
  • Externe 64-Bit-Objektdateien: Wenn Sie Ihre 64-Bit-Windows-Anwendung mit einer externen Objektdatei (.obj) linken möchten, benötigen Sie eine 64-Bit-Version der .obj-Datei zum Linken mit einer 64-Bit-Windows-Anwendung.

Siehe auch