确定uint32_t的字节顺序

时间:2011-10-27 20:27:21

标签: c++ linux vxworks

我正在将vxWorks应用程序转换为Linux。

以前,我有union wordstruct,因此当我访问struct的成员时,我可以使用word's } layout用于构建我的struct成员。

但是,我不记得我是如何理解这一点的,它适用于vxWorks盒子。在我的vxWorks实例上,布局为:

typedef union Status
{
    struct fields
    {
        uint32_t byteA : 1; // <31>
        uint32_t blank : 23; // <30:8>
        uint32_t bytesN : 8; // <7:0>
    } fields;

    uint32_t word;
}

从vxWorks移植到Linux时,我已经遇到了一些端点问题。因此,在linux上找出uint32_t的布局非常重要。

2 个答案:

答案 0 :(得分:3)

您可以通过指向包含值0x01的int并将其转换为char *来指示。如果第一个值等于零,那么系统是大端,否则它是小端。

以下是一个例子:

#include <inttypes.h>
#include <stdio.h>

int main(void)
{
   uint32_t   val  = 0x01;
   char     * buff = (char *)&val;

   if (buff[0] == 0)
   {
      printf("Big endian\n");
   } else {
      printf("Little endian\n");
   };

   return(0);
}

我在Linux,Solaris,OS X和FreeBSD上使用过这种方法。

答案 1 :(得分:1)

从您的评论到其他answer,您希望填充到word union成员中的任何内容都显示在fields.bytesN成员中。要实现这一点,您必须具有某种预构建过程,该过程在检测到机器字节序后适当地布置field位字段,或者创建2个结构,一个用于大端,另一个用于小端。

typedef union Status
{
    struct fieldsBE
    {
        uint32_t byteA : 1; // <31>
        uint32_t blank : 23; // <30:8>
        uint32_t bytesN : 8; // <7:0>
    } fieldsBE;

    struct fieldsLE
    {
        uint32_t bytesN : 8; // <7:0>
        uint32_t blank : 23; // <30:8>
        uint32_t byteA : 1; // <31>
    } fieldsLE;

    uint32_t word;
};

int main()
{
  bool isBigEndian = DetectEndianness(); // returns true if big endian

  Status status;

  status.word = 40;

  if( isBigEndian ) {
    uint8_t bytesN = status.fieldsBE.bytesN;

  } else {
    uint8_t bytesN = status.fieldsLE.bytesN;

  }
}

当然,如果您只想支持端口中的小端,请使用fieldsLE的布局,而不是您显示的原始布局。