字节序变通所需 [英] Endianness Work-around Needed

查看:132
本文介绍了字节序变通所需的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的一块code的:

Consider the following piece of code:

#include "stdio.h"

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

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

void F1(CustomStruct* X)
{
  F2((char *)X);
  printf("s = %x\n", (*X).Element1[0]);
}

int main(void)
{
  CustomStruct s;
  F1(&s);

  return 0;
}

在运行时,通过调用函数 F1 结束后,我通过使用不同的编译器得到不同的结果。

At run-time, by the end of calling the function F1, I get different results by using different compilers.

(* X).Element1 [0] = 0x1f00 在一些编译器和(* X).Element1 [0] = 0x001f 用另一个。

(*X).Element1[0] = 0x1f00 in some compiler and (*X).Element1[0] = 0x001f with another one.

很明显,我认为这是一个字节序的问题。

It's clear to me that it's an endianness issue.

是否有任何编译器选项或变通使用,使我得到(* X).Element1 [0] = 0x001f 无论使用编译器?

Is there any compiler option or work-around to use so that I get (*X).Element1[0] = 0x001f regardless the used compiler?

推荐答案

字节序是不是一个编译器的问题,甚至也不是一个操作系统的问题,而是一个平台的问题。有没有编译器选项或变通的字节顺序。然而有转换程序,让您可以正常化存储的数据的字节序。

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.

ntoh 记录将重新排序字节指出,从网络的顺序(big endian)的举办顺序(无论是大或小,这取决于主机的类型)。也有走在相反的方向,从主机以网络订单 hton 功能。

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.

下面是我写的 ntohx htonx 这是在数据存储的类型一概而论,是函数模板它有2个字节,4个或者8个字节的类型:

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));
};

这篇关于字节序变通所需的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆