字节顺序不是编译器问题,甚至不是操作系统问题,而是平台问题。字节序没有编译器选项或“解决方法”。然而,有一些转换例程,以便您可以标准化存储数据的字节顺序。
此处记录的ntoh
例程会将指向的字节重新排序,从网络顺序(大端)到主机顺序(大或小,取决于主机的类型)。还有一些功能是相反的,从主机顺序到网络顺序。hton
如果要规范化存储在数据结构中的字节,则需要在存储数据或尝试读取数据时自己进行。
以下是我编写的函数模板ntohx
,htonx
它们概括了数据存储的类型,无论是 2 字节、4 字节还是 8 字节类型:
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));
};