c++ - 需要字节序解决方法

标签 c++ c pointers endianness cpu-architecture

考虑以下代码:

#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 结束时,我通过使用不同的编译器得到了不同的结果。

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

我很清楚这是一个字节顺序问题。

是否有任何编译器选项或解决方法可供使用,以便无论使用何种编译器,我都能得到 (*X).Element1[0] = 0x001f

最佳答案

Endianness不是编译器问题,甚至也不是操作系统问题,而是平台问题。字节顺序没有编译器选项或“解决方法”。但是,有一些转换例程,以便您可以规范存储数据的字节顺序。

ntoh 例程 documented here会将指向的字节从网络顺序(大端)重新排序为主机顺序(大或小,取决于主机的类型)。还有一些 hton 函数,它们的方向相反,从主机顺序到网络顺序。

如果要规范化存储在数据结构中的字节,则需要在存储数据或尝试读取数据时自行完成。

以下是我为 ntohxhtonx 编写的函数模板,这些模板在数据存储类型上进行了概括,无论是 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));
};

关于c++ - 需要字节序解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17448573/

相关文章:

c++ - Clang 或 GCC 拒绝/接受此 CTAD 代码是否正确?

c - C中参数数量可变的函数的奇怪行为

c - 分配二维数组后字符串被截断(已编辑)

java - 实现移植到 Java 的指针和数组

以指针为返回值的C++嵌套函数

c++ - Qt- new QThread(this) 和 new QThread() 有什么区别?

c++ - Qt Creator 问题。构建项目时未显示 UI 更改

c++ - 在 linux 下链接库时 Cython 构建问题

C - System V - 删除共享内存段

我可以检查指针是否已分配给 malloc 以外的东西吗?