Endianness Work-around Needed

后端 未结 2 1881
再見小時候
再見小時候 2021-01-17 01:03

Consider the following piece of code:

#include \"stdio.h\"

typedef struct CustomStruct
{
  short Element1[10];
}CustomStruct;

void F2(char* Y)
{
  *Y=0x00;         


        
相关标签:
2条回答
  • 2021-01-17 01:25

    Endianness is not a compiler issue, nor even an operating system issue, but a platform issue. There are no compiler options or "workarounds" for endianness. There are however conversion routines so that you can normalize the endianness of stored data.

    The ntoh routines documented here will reorder the bytes pointed to from network order (big endian) to host order (either big or little, depending on the type of host). There are also hton functions that go in the opposite direction, from host order to network order.

    If you want to normalize the bytes stored in your data structure, you need to do it yourself either when you store the data or when you try to read it.

    Here are function templates I wrote for ntohx and htonx that are generalized on the type of data store, be it a 2 byte, 4 byte or 8 byte type:

    template<class Val> inline Val ntohx(const Val& in)
    {
        char out[sizeof(in)] = {0};
        for( size_t i = 0; i < sizeof(Val); ++i )
            out[i] = ((char*)&in)[sizeof(Val)-i-1];
        return *(reinterpret_cast<Val*>(out));
    }
    
    template<> inline unsigned char ntohx<unsigned char>(const unsigned char & v )
    {
        return v;
    }
    template<> inline uint16_t ntohx<uint16_t>(const uint16_t & v)
    {
        return ntohs(v);
    }
    
    template<> inline uint32_t ntohx<uint32_t>(const uint32_t & v)
    {
        return ntohl(v);
    }
    
    template<> inline uint64_t ntohx<uint64_t>(const uint64_t & v)
    {
        uint32_t ret [] =
        {
            ntohl(((const uint32_t*)&v)[1]),
            ntohl(((const uint32_t*)&v)[0])
        };
        return *((uint64_t*)&ret[0]);
    }
    template<> inline float ntohx<float>(const float& v)
    {
        uint32_t const* cast = reinterpret_cast<uint32_t const*>(&v);
        uint32_t ret = ntohx(*cast);
        return *(reinterpret_cast<float*>(&ret));
    };
    
    template<class Val> inline Val htonx(const Val& in)
    {
        char out[sizeof(in)] = {0};
        for( size_t i = 0; i < sizeof(Val); ++i )
            out[i] = ((char*)&in)[sizeof(Val)-i-1];
        return *(reinterpret_cast<Val*>(out));
    }
    
    template<> inline unsigned char htonx<unsigned char>(const unsigned char & v )
    {
        return v;
    }
    template<> inline uint16_t htonx<uint16_t>(const uint16_t & v)
    {
        return htons(v);
    }
    
    template<> inline uint32_t htonx<uint32_t>(const uint32_t & v)
    {
        return htonl(v);
    }
    
    template<> inline uint64_t htonx<uint64_t>(const uint64_t & v)
    {
        uint32_t ret [] =
        {
            htonl(((const uint32_t*)&v)[1]),
            htonl(((const uint32_t*)&v)[0])
        };
        return *((uint64_t*)&ret[0]);
    }
    template<> inline float htonx<float>(const float& v)
    {
        uint32_t const* cast = reinterpret_cast<uint32_t const*>(&v);
        uint32_t ret = htonx(*cast);
        return *(reinterpret_cast<float*>(&ret));
    };
    
    0 讨论(0)
  • 2021-01-17 01:29

    If F2() is receiving a char *, then it must be doing something pretty strange in order to cause endian-related problems.

    These only happen when accessing more than one char at a time, unless it's manually doing such accesses while being broken. Is it casting it's argument back to short * or something?

    In short, show more code.

    0 讨论(0)
提交回复
热议问题