web-dev-qa-db-fra.com

Comment dois-je préparer mes programmes Delphi 32 bits pour un éventuel compilateur 64 bits?

Duplicate possible:
Comment préparer également la version 64 bits lors de la migration vers Delphi 2010 et Unicode

Puisque je crois que le compilateur Delphi 64bit apparaîtra bientôt, je me demande si quelqu'un sait quel genre de programmes qui sont maintenant 32bit compileront et fonctionneront sans changement si vous utilisez 64bit compilateur.

Et s’il existe une règle générale, quels types de modifications devrions-nous systématiquement apporter à nos anciens programmes afin de les compiler en tant que 64bit ?

Il est bon de se préparer lorsque le compilateur 64bit sera soudainement arrivé ...

Toute suggestion sera très appréciée.

59
Petra

Tout d'abord, un avertissement: bien que je travaille pour Embarcadero. Je ne peux pas parler pour mon employeur. Ce que je suis sur le point d'écrire est basé sur ma propre opinion sur le fonctionnement d'un Delphi 64 bits hypothétique, mais il peut exister ou non des opinions contradictoires et d'autres incompatibilités prévues ou imprévues qui entraînent la prise de décisions de conception alternatives.

Cela dit:

  • Il existe deux types d'entiers, NativeInt et NativeUInt, dont la taille varie entre 32 et 64 bits selon la plate-forme. Ils ont été autour depuis un certain nombre de versions. Aucun autre type entier ne changera de taille en fonction du nombre de bits de la cible.

  • Assurez-vous que tout endroit qui repose sur la conversion d'une valeur de pointeur en entier ou inversement utilise NativeInt ou NativeUInt pour le type entier. TComponent.Tag doit être NativeInt dans les versions ultérieures de Delphi.

  • Je suggérerais n'utilisez pas NativeInt ou NativeUInt pour des valeurs non basées sur un pointeur . Essayez de garder votre code sémantiquement identique entre 32 bits et 64 bits. Si vous avez besoin de 32 bits de plage, utilisez Integer; Si vous avez besoin de 64 bits, utilisez Int64. De cette façon, votre code devrait être identique sur les deux bits. N'utilisez NativeInt que si vous appelez depuis et vers une valeur de pointeur quelconque, telle qu'une référence ou un THandle.

  • Utilisez PByte pour l'arithmétique du pointeur, si possible, de préférence à NativeInt ou NativeUInt. Cela suffira dans la plupart des cas, et est plus typé car cela ne peut pas (facilement) être confondu avec un type entier normal, et vice versa.

  • Les choses de type pointeur devraient suivre des règles similaires aux pointeurs: les références d'objet (évidemment), mais aussi des choses comme HWND, THandle, etc.

  • Ne vous fiez pas aux détails internes des chaînes et des tableaux dynamiques, comme leurs données d'en-tête.

  • Notre politique générale sur les modifications d'API pour les versions 64 bits devrait consister à conserver la même API entre les versions 32 bits et 64 bits, si possible, même si cela signifie que l'API 64 bits ne tire pas nécessairement parti de la machine. Par exemple, TList ne traitera probablement que les éléments MaxInt div SizeOf (pointeur), afin de conserver le nombre, les index, etc. en tant qu'entier. Parce que le type Integer ne flotte pas (c.-à-d. Que sa taille dépend du nombre de bits), nous ne voulons pas d'effets d'entraînement sur le code client: tout index arrondi à l'aide d'une variable de type Integer ou d'un index for-loop être tronqué et potentiellement causer des bugs subtils.

  • Lorsque les API sont étendues pour 64 bits, elles seront très probablement associées à une fonction/méthode/propriété supplémentaire permettant d'accéder aux données supplémentaires. Cette API sera également prise en charge en 32 bits. Par exemple, la routine standard Length () renverra probablement les valeurs de type Integer pour les arguments de type chaîne ou tableau dynamique; si l'on veut gérer de très grands tableaux dynamiques, il peut également y avoir une routine LongLength (), dont l'implémentation en 32 bits est identique à Length (). Length () lève une exception en 64 bits si elle est appliquée à un tableau dynamique comportant plus de 2 ^ 32 éléments.

  • Dans le même ordre d'idées, la vérification des erreurs sera probablement améliorée pour les opérations de restriction dans le langage, en particulier pour réduire les valeurs 64 bits aux emplacements 32 bits. Cela nuirait à la possibilité d'assigner la valeur de retour de Length aux emplacements de type Integer si Length (), renvoyé Int64. D'autre part, en particulier pour les fonctions magiques du compilateur telles que Length (), il peut y avoir un avantage de la magie prise, par exemple. changer le type de retour en fonction du contexte. Mais les avantages ne peuvent pas être pris de la même manière dans les API non magiques.

  • Les tableaux dynamiques prendront probablement en charge l'indexation 64 bits. Notez que les baies Java sont limitées à l'indexation 32 bits, même sur les plates-formes 64 bits.

  • Les chaînes seront probablement limitées à l'indexation 32 bits. Nous avons du mal à trouver des raisons réalistes pour lesquelles les utilisateurs veulent des chaînes de 4 Go ou plus, et pas seulement des blocs de données gérées, pour lesquels les tableaux dynamiques peuvent aussi bien servir.

  • Peut-être un assembleur intégré, mais avec des restrictions, comme ne pas pouvoir mélanger librement avec du code Delphi; il existe également des règles relatives aux exceptions et à la disposition du cadre de pile qui doivent être suivies sur x64.

80
Barry Kelly

Tout d’abord, FreePascal offre déjà un support 64 bits. Ce n'est pas Delphi, cependant.
Deuxièmement, je m'attends à peu près aux mêmes problèmes qui existaient au moment où Delphi 1 a été mis à niveau vers Delphi 2. Le plus gros problème est principalement lié à l’adresse, et le problème ici est que les pointeurs seront élargis de 4 octets à 8 octets. Dans WIN16, ils utilisaient généralement 2 octets et il fallait une astuce pour franchir la limite de 64 Ko en utilisant des segments et des décalages pour les pointeurs. (Avec la possibilité d'utiliser des segments par défaut pour plusieurs tâches.)
Il est également probable que certains types de données deviennent plus gros qu’aujourd’hui. Le type entier sera 8 octets, le plus probable. (Utilisé pour n'être que 2 octets dans Windows 2.) Les énumérations deviendront probablement aussi plus grandes. Mais la plupart des autres types de données conserveront probablement leur taille actuelle, il ne faut donc pas trop de changements ici.
Un autre problème sera la mémoire requise. Les pointeurs ayant une longueur de 8 octets, une application qui en utilise beaucoup consommera également beaucoup plus de mémoire. Une liste de 10 000 pointeurs passera de 40 000 octets à 80 000 octets. Vous voudrez peut-être utiliser un peu plus de mémoire que sur un système 32 bits.
La vitesse changera aussi un peu. Étant donné que le processeur gère maintenant 8 octets en même temps, il peut traiter les données beaucoup plus rapidement. Mais comme les pointeurs et certains types de données deviennent plus gros, leur réception ou leur envoi vers un périphérique ou une mémoire sera un peu plus lent. En général, vos applications seront légèrement plus rapides en général, mais certaines parties risquent en fait de devenir plus lentes!
Enfin, les modifications apportées à l'API Windows nécessiteront l'utilisation des fonctions de l'API 64 bits. Peut-être que le compilateur Delphi fera quelque chose d'intelligent pour permettre au code d'appeler des fonctions d'API 32 bits, mais cela ralentirait les performances car le processeur bascule désormais entre le mode natif 64 bits et le mode émulé 32 bits.

8
Wim ten Brink

De nombreuses questions similaires ont été posées lorsqu'il a été annoncé que Delphi 2009 ne créerait que des applications Unicode. En fin de compte, il s’est avéré que la plupart du code existant fonctionnait parfaitement sans modifications. Les parties difficiles étaient du code qui supposait que SizeOf(Char) = 1 et des composants tiers pouvaient le faire.

Je m'attendrais à ce que le passage à Delphi 64 bits soit une expérience similaire. Tout fonctionne parfaitement, à l'exception du code qui joue des tours avec des pointeurs et suppose que SizeOf(Pointer) = 4 ou SizeOf(Pointer) = SizeOf(Integer). Vous pouvez déjà résoudre ces problèmes aujourd'hui en appelant SizeOf(Pointer) au lieu de coder en dur 4 et en utilisant NativeInt ou NativeUInt lorsque vous avez besoin d'entiers de la taille d'un pointeur.

Vous devez utiliser SizeOf(Pointer) plutôt que SizeOf(NativeInt) si vous voulez que votre code fonctionne avec Delphi 2007. Delphi 2007 a un bogue malheureux qui fait que SizeOf(NativeInt) renvoie 8 au lieu de 4 comme il se doit. Ce problème a été corrigé dans Delphi 2009.

4
Jan Goyvaerts

Selon votre code, vous pouvez essayer de le compiler en utilisant FreePascal, qui prend en charge les compilations 32 bits et 64 bits. Le compilateur vous avertira des endroits éventuellement erronés dans votre code.

Tant qu'Embarcadero ne publie pas d'informations officielles sur leur implémentation 64 bits, ce n'est pas facile à dire. Vous devez vérifier toute conversion vers/depuis le pointeur, l'entier et le cardinal en supposant qu'il s'agit de la taille de la plate-forme native, y compris les propriétés de l'objet et les références (c'est-à-dire stocker un entier dans une propriété TObject, qui est un pointeur, ou en utilisant Tag pour stocker des références et non des nombres ).

Vous devez également vous assurer qu'aucun code ne repose sur l'effet de "bouclage" lors de l'incrémentation (ou la décrémentation) d'une valeur à sa taille maximale (minimale).

Vérifiez tous les codes dans les structures qui dépendent de la taille des données et n'utilisez pas SizeOf () correctement. En règle générale, SizeOf () est toujours utilisé lorsque la taille de la donnée est importante. Vérifiez le code qui écrit/lit les données dans les fichiers, si la taille peut changer, en particulier si les données doivent être échangées entre du code 32 et 64 bits.

Vérifiez les modifications Win64 si l'application appelle l'API et gère directement les messages Windows. Le code ASM codé à la main doit être vérifié pour la compatibilité 64 bits (il existe une règle beaucoup plus stricte pour écrire un assembleur 64 bits).

3
user160694

La grande majorité des applications simples devrait fonctionner correctement. Autant que je sache, seules les applications utilisant manuellement les pointeurs présentent un risque. En effet, si un pointeur est maintenant à 64 bits et que vous l'utilisez dans des calculs avec des entiers ou des cardinaux (qui sont toujours à 32 bits par défaut), vous aurez des problèmes. Je pense également qu'il est assez courant que les déclarations de fonctions API prenant les pointeurs comme arguments utilisent cardinals au lieu du type entier natif (non signé).

Pour que le code fonctionne bien sur n’importe quelle plate-forme, vous devez utiliser NativeUInts (IIRC, n’ayant pas de compilateur Deplhi pour le moment) au lieu de cardinals lorsque vous travaillez avec des pointeurs et des entiers simultanément.

3
Andreas Rejbrand

Outre le pointeur évident <-> tâches int: (en utilisant intptr/nativeint/ptrint etc.)

  • Tout ce que vous avez en tant que blob binaire (DLL, peut-être OCX, etc.) doit être mis à niveau. Cela peut inclure d'anciens SDK pour les dongles, etc.
  • Tous les outils qui font quelque chose au niveau binaire (débogueurs, profileurs, outils de téléphone à la maison) peuvent nécessiter des mises à jour.
  • Presque tous les assembleurs et autres astuces de très bas niveau (par exemple, dépendant de la disposition VMT, du format de débogage (suivi), des talons de chargement dynamique comme dans Jedi Apilib, etc.) doivent être mis à jour.
  • vérifiez tous les en-têtes créés pour connaître les modifications d'emballage et de traduction qui importent maintenant pointeur <> entier. Le bit d'emballage ne doit pas être sous-estimé
  • L'interfaçage avec Office et d'autres applications externes peut changer
  • TComponent.tag est une instruction longue maintenant, et peut donc rester longue, ce qui signifie que les schémas qui intègrent des pointeurs dans composant.tag peuvent échouer.
  • x87 FPU est obsolète sur x64 et, en général, SSE2 sera utilisé pour le point de floraison. ainsi, la virgule flottante et sa gestion des exceptions peuvent fonctionner légèrement différemment, et extended ne doit pas être en 80 bits (mais en 64 bits ou moins vraisemblablement en 128 bits). Cela concerne également les modifications d’arrondi (contrôle du copro) habituelles lors de l’interfaçage avec du code C qui attend un autre fpu Word.

Le problème d'emballage des enregistrements est quelque chose que j'ai remarqué lors du portage d'en-têtes existants sur win64.

2
Marco van de Voort

Mes 2 centimes:

  • dans l'ancien temps, chaque auteur asm devait pousser à utiliser BASM

  • asm64 externe serait acceptable et l’utilisation de l’ancien code inlclude xy.obj, bien qu’une réécriture complète soit nécessaire

  • Debugger & CPU64: la question sera: est-ce toujours là ??

  • D64 Float Extended: Est-ce toujours maintenu en tant que float 80 bits?

Hp

1
HpW

Comme une supposition complète, tout code qui ne dépend pas d'une taille de Word spécifique, ou peut adapter sa taille de Word en fonction de ce que le compilateur lui dit, ira bien.

0