4 votes

Une simple transition de 32 à 64 bits ?

Existe-t-il un moyen simple de compiler un code C 32 bits en une application 64 bits, avec un minimum de modifications ? Le code n'a pas été configuré pour utiliser des tailles de caractères fixes.

Je ne souhaite pas profiter de l'adressage mémoire 64 bits. J'ai juste besoin de compiler dans un binaire 64 bits tout en conservant les longueurs de 4 octets et les pointeurs.

Quelque chose comme :

#define long int32_t

Mais bien sûr, cela casse un certain nombre de cas d'utilisation longs et ne traite pas les pointeurs. J'ai pensé qu'il pourrait y avoir une procédure standard ici.

3voto

Kerrek SB Points 194696

Il semble y avoir deux notions orthogonales de "portabilité" :

  1. Mon code se compile partout sans problème. Son comportement général est le même sur toutes les plateformes, mais les détails des fonctionnalités disponibles varient en fonction des caractéristiques de la plateforme.

  2. Mon code contient un dossier pour les éléments dépendant de l'architecture. Je garantis que MYINT32 est toujours 32 bits, quoi qu'il arrive. J'ai réussi à transposer la notion de 32 bits aux lummoxes à fourrure à neuf doigts de Mars.

Dans la première approche, nous écrivons unsigned int n; y printf("%u", n) et nous savons que le code fonctionne toujours, mais des détails comme la gamme numérique de unsigned int sont du ressort de la plate-forme et ne nous concernent pas. ( Wchar_t entre en jeu ici aussi). C'est ce que j'appellerais le style véritablement portable.

Dans la deuxième approche, nous définissons tout et utilisons des types comme uint32_t . Sortie formatée avec printf déclenche des tonnes d'avertissements, et nous devons recourir à des monstres comme PRI32 . Cette approche nous procure un étrange sentiment de puissance et de contrôle en nous permettant de savoir que notre entier a toujours une largeur de 32 bits, mais j'hésite à qualifier cette approche de "portable" : elle est tout simplement têtue.

Le concept fondamental qui nécessite une représentation spécifique est sérialisation : Le document que vous écrivez sur une plateforme doit être lisible sur toutes les autres plateformes. La sérialisation est naturellement l'endroit où l'on renonce au système de types, où l'on doit s'inquiéter de l'endive et où l'on doit décider d'une représentation fixe (y compris des choses comme l'encodage du texte).

Le résultat est le suivant :

  • Écrivez le noyau de votre programme principal dans un style portable en utilisant des primitives de langage standard.
  • Écrire des interfaces d'E/S propres et bien définies pour la sérialisation.

Si vous vous en tenez à cela, vous ne devriez même pas avoir à vous demander si votre plate-forme est 32 ou 64 bits, big ou little endian, Mac ou PC, Windows ou Linux. Respectez la norme, et la norme vous suivra.

2voto

caf Points 114951

Non, ce n'est pas possible, en général. Considérez, par exemple, malloc() . Que doit-il se passer lorsqu'il renvoie une valeur de pointeur qui ne peut être représentée en 32 bits ? Comment cette valeur de pointeur peut-elle être transmise à votre code comme une valeur 32 bits, qui fonctionnera correctement lorsqu'elle sera déréférencée ?

Ce n'est qu'un exemple - il en existe de nombreux autres similaires.

Un code C bien écrit n'est pas intrinsèquement "32 bits" ou "64 bits" de toute façon - il devrait fonctionner sans problème lorsqu'il est recompilé en tant que binaire 64 bits sans aucune modification nécessaire.


Votre problème réel est de vouloir charger une bibliothèque 32 bits dans une application 64 bits. Une façon de le faire est d'écrire une application auxiliaire 32 bits qui charge votre bibliothèque 32 bits, et une bibliothèque shim 64 bits qui est chargée dans l'application 64 bits. Votre bibliothèque de shim 64 bits communique avec votre application auxiliaire 32 bits à l'aide d'un mécanisme IPC, demandant à l'application auxiliaire d'effectuer des opérations en son nom, et renvoyant les résultats.

Le cas spécifique - un fichier MEX de Matlab - pourrait être un peu compliqué (vous aurez besoin d'un appel de fonction bidirectionnel, afin que la bibliothèque shim 64 bits puisse effectuer des appels tels que mexGetVariable() au nom de l'assistant 32 bits), mais cela devrait être faisable.

0voto

jbruni Points 961

La seule chose qui vous piquera probablement, c'est si l'un de vos entiers 32 bits est manipulé en bits. Si vous supposez que certains drapeaux d'état sont stockés dans un registre 32 bits (par exemple), ou si vous effectuez des décalages de bits, vous devrez vous concentrer sur ces derniers.

Un autre endroit où chercher serait tout code réseau qui suppose la taille (et l'endienne) des entiers transmis sur le fil. Une fois que ces derniers auront été déplacés vers des ints 64 bits, vous devrez vous assurer que vous ne perdez pas de bits de signe ou de précision.

Les structures qui contiennent des entiers n'auront plus la même taille. Toutes les hypothèses sur la taille et l'alignement doivent être nettoyées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X