Maison > développement back-end > C++ > Comment obtenir la portabilité lors de la conversion d'entiers 64 bits en ordre d'octets réseau en C ?

Comment obtenir la portabilité lors de la conversion d'entiers 64 bits en ordre d'octets réseau en C ?

Susan Sarandon
Libérer: 2024-10-30 04:37:28
original
936 Les gens l'ont consulté

How to Achieve Portability When Converting 64-Bit Integers to Network Byte Order in C  ?

Problèmes de portabilité pour les conversions d'ordre d'octets réseau d'entiers de 64 bits en C

En C, il est nécessaire de convertir des entiers de 64 bits à « l'ordre des octets du réseau » pour des applications spécifiques, telles que la mise en œuvre du protocole Memcache. Malgré l'existence de la fonction htonl() pour convertir des entiers 32 bits, une fonction similaire pour les entiers 64 bits (htonll()) reste insaisissable.

Considérations sur les fonctions standard

Malheureusement, il n'existe actuellement aucune fonction standard portable en C capable d'effectuer des conversions de l'ordre des octets du réseau 64 bits. Cette absence crée le besoin d'implémentations personnalisées.

Implémentation personnalisée

Pour implémenter htonll(), nous devons d'abord déterminer le caractère boutien du système. Une méthode fiable consiste à évaluer la valeur d'une variable entière avec un ordre d'octets connu (par exemple, 42) au moment de l'exécution :

<code class="cpp">static const int num = 42;
bool isBigEndian = (*reinterpret_cast<const char *>(&num) == num);</code>
Copier après la connexion

Ensuite, nous pouvons effectuer la conversion en fonction du caractère boutien :

<code class="cpp">uint64_t htonll(uint64_t value)
{
    if (isBigEndian)
    {
        const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
        const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));

        return (static_cast<uint64_t>(low_part) << 32) | high_part;
    }
    else
    {
        return value;
    }
}
Copier après la connexion

Macros pour la portabilité

Alternativement, les macros peuvent fournir un moyen concis de définir htonll() et son homologue, ntohll() :

<code class="cpp">#define htonll(x) ((1 == htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
#define ntohll(x) ((1 == ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))</code>
Copier après la connexion

Ces les macros s'appuient sur le comportement intrinsèque de l'ordre des octets du système pour déterminer l'échange d'octets nécessaire.

Macros spécifiques au compilateur

Certains compilateurs et systèmes d'exploitation fournissent des macros spécifiques pour déterminer l'endianité . Par exemple, sur les systèmes qui le prennent en charge, nous pouvons utiliser :

<code class="cpp">#if __BIG_ENDIAN__
# define htonll(x) (x)
# define ntohll(x) (x)
#else
# define htonll(x) (((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
# define ntohll(x) (((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
#endif</code>
Copier après la connexion

En employant ces techniques, les implémentations personnalisées de htonll() et ntohll() peuvent être rendues portables sur divers systèmes et compilateurs.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal