How do I convert between big-endian and little-endian values in C++?

前端 未结 30 2960
难免孤独
难免孤独 2020-11-21 23:18

How do I convert between big-endian and little-endian values in C++?

EDIT: For clarity, I have to translate binary data (double-precision floating point values and 3

30条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-21 23:57

    I have this code that allow me to convert from HOST_ENDIAN_ORDER (whatever it is) to LITTLE_ENDIAN_ORDER or BIG_ENDIAN_ORDER. I use a template, so if I try to convert from HOST_ENDIAN_ORDER to LITTLE_ENDIAN_ORDER and they happen to be the same for the machine for wich I compile, no code will be generated.

    Here is the code with some comments:

    // We define some constant for little, big and host endianess. Here I use 
    // BOOST_LITTLE_ENDIAN/BOOST_BIG_ENDIAN to check the host indianess. If you
    // don't want to use boost you will have to modify this part a bit.
    enum EEndian
    {
      LITTLE_ENDIAN_ORDER,
      BIG_ENDIAN_ORDER,
    #if defined(BOOST_LITTLE_ENDIAN)
      HOST_ENDIAN_ORDER = LITTLE_ENDIAN_ORDER
    #elif defined(BOOST_BIG_ENDIAN)
      HOST_ENDIAN_ORDER = BIG_ENDIAN_ORDER
    #else
    #error "Impossible de determiner l'indianness du systeme cible."
    #endif
    };
    
    // this function swap the bytes of values given it's size as a template
    // parameter (could sizeof be used?).
    template 
    inline T SwapBytes(T value)
    {
      union
      {
         T value;
         char bytes[size];
      } in, out;
    
      in.value = value;
    
      for (unsigned int i = 0; i < size / 2; ++i)
      {
         out.bytes[i] = in.bytes[size - 1 - i];
         out.bytes[size - 1 - i] = in.bytes[i];
      }
    
      return out.value;
    }
    
    // Here is the function you will use. Again there is two compile-time assertion
    // that use the boost librarie. You could probably comment them out, but if you
    // do be cautious not to use this function for anything else than integers
    // types. This function need to be calles like this :
    //
    //     int x = someValue;
    //     int i = EndianSwapBytes(x);
    //
    template
    inline T EndianSwapBytes(T value)
    {
      // A : La donnée à swapper à une taille de 2, 4 ou 8 octets
      BOOST_STATIC_ASSERT(sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
    
      // A : La donnée à swapper est d'un type arithmetic
      BOOST_STATIC_ASSERT(boost::is_arithmetic::value);
    
      // Si from et to sont du même type on ne swap pas.
      if (from == to)
         return value;
    
      return SwapBytes(value);
    }
    

提交回复
热议问题