2010-10-06 17 views
7

Ma bibliothèque doit lire les entiers big-endian (4-bytes) et les convertir en ordre endian de l'hôte pour le traitement. Alors que sur * nix ntohl a travaillé un régal sous Windows utilisation de ntohl nécessite l'utilisation de Ws2_32.dll (Winsock).Détection de l'endianness avec CMake

Une telle dépendance est celle que je préférerais éliminer. La façon la plus simple de le faire semble être d'écrire ma propre fonction d'échange endian (un exercice trivial, considérant que la performance n'est pas une réelle préoccupation). Cependant, cela nécessite un moyen de déterminer l'endianness du système sur lequel ma bibliothèque est compilée (donc je peux #ifdef sortir la fonction de permutation sur les systèmes big endian). Comme il ne semble pas y avoir de définition de préprocesseur standard pour endianess, il semble qu'il soit nécessaire de le déterminer en utilisant mon système de compilation (cmake). Quel est le meilleur moyen de le faire? (Je suis fatigué de 'compiler un fichier de test et de voir' les solutions de type car elles sembleraient empêcher la compilation croisée.)

+3

Remarque: CMake a effectivement un soutien raisonnable pour la compilation croisée. Pour les contrôles nécessitant l'exécution d'un programme de test, il crée le programme de test et attend que vous définissiez les variables de cache sur le résultat correct. Voir http://www.paraview.org/Wiki/CMake_Cross_Compiling. Avoir un upvote pour s'occuper de la compilation croisée. –

Répondre

6

Édité: Je vois que cmake a un script TestBigEndian.cmake, mais cela fait une compilation et un test de voyez si le système est Big Endian ou non, ce qui n'est pas ce que vous voulez faire.

Vous pouvez vérifier l'endianness du système dans votre propre programme avec une fonction comme celle-ci. Fondamentalement créer un nombre entier, et lire son premier octet (octet le moins significatif)

bool isLittleEndian() 
{ 
    short int number = 0x1; 
    char *numPtr = (char*)&number; 
    return (numPtr[0] == 1); 
} 
Si cet octet est 1, alors le système est peu endian, sinon c'est gros endian.

Toutefois, cela ne vous permet pas de déterminer l'endianness avant l'exécution. Si vous voulez la détermination du temps de compilation de l'endianness du système, je ne vois pas beaucoup d'alternative à la construction d'un programme de test et ensuite compiler mon vrai programme à la cmake, ou faire des vérifications exhaustives pour des macros spécifiques définies par les compilateurs, par exemple __BIG_ENDIAN__ sur GCC 4.x.

MISE À JOUR Vous pouvez également jeter un coup d'œil au modèle endian.hpp de Boost. http://www.boost.org/doc/libs/1_43_0/boost/detail/endian.hpp

+0

"Toutefois, cela ne vous permet pas de déterminer l'endianness avant l'exécution." - Vous pouvez faire quelque chose comme ceci, et il devrait être évalué au moment de la compilation: const bool g_isLittleEndian = isLittleEndian(); – darklon

+0

La variable @darklon 'const' n'est pas strictement évaluée au moment de la compilation. Il peut et sera évalué à l'exécution puisque 'isLittleEndian()' utilise des variables. Pour le rendre strictement évalué au moment de la compilation, le mot-clé 'constexpr' ou une technique de métaprogrammation de modèle devrait être utilisé. (La raison pour laquelle je pensais que 'const bool g_isLittleEndian = isLittleEndian();' sera évaluée lors de l'exécution est parce que '(char *) (& nombre)' n'est pas une expression constante.C'est ce que GCC dit quand vous déclarez 'numPtr' comme 'constexpr') – minary