Определить порядок байтов uint32_t

Я конвертирую приложение vxWorks в Linux.

Раньше у меня был union с word и struct, так что когда я обращался к элементам struct, я мог использовать макет word's для создания своих 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. Поэтому важно выяснить расположение uint32_t в Linux.


person Community    schedule 27.10.2011    source источник
comment
разве что-то вроде этого не должно сработать? uint32_t foobar = 0x00ff00ff; if (((char *) foobar)[0] == 0xff) /* one endianess */ else /* the other */   -  person Alexander Oh    schedule 28.10.2011
comment
Вы спрашиваете о stackoverflow.com/questions/6359629/?   -  person Gnawme    schedule 28.10.2011


Ответы (2)


Из вашего комментария к другому ответу вы хотите, чтобы все было вставляется в 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 вместо исходного макета, который вы показали.

person Praetorian    schedule 27.10.2011
comment
но мне пришлось изменить байты N на 31, пробел на 23 и byteA на 1. - person ; 28.10.2011

Вы можете узнать это, взяв указатель на int, содержащий значение 0x01, и приведя его к 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.

person David M. Syzdek    schedule 27.10.2011
comment
Да, я знаю, как это сделать. Но если word содержит число 40, я хочу, чтобы это число было в байтахN, а не в пустом виде или в байтахA. Вот почему макет важен. Как конкретно выложен uint32_t. - person ; 28.10.2011
comment
@ 0A0D Так ты хочешь это сделать? Status x; x.word=40; printf("%d", x.fields.bytesN); - person anatolyg; 28.10.2011
comment
Ваша проблема в том, что вы не меняете порядок доступа к байтам при доступе Status.word. На оборудовании с обратным порядком байтов целое число хранится как B3,B2,B1,B0, однако на оборудовании с прямым порядком байтов целое число хранится как B0,B1,B2,B3. Это означает, что на оборудовании с прямым порядком байтов ((Status .fields.byteN == 15) && (Status.word == 0x0F)), тогда как на оборудовании с прямым порядком байтов ((Status .fields.byteN == 15) && (Status.word == 0x0F000000)) При переключении с платформы с обратным порядком байтов необходимо либо изменить порядок битов Status.fields, либо изменить порядок битов, используемый для доступа к Status.word. - person David M. Syzdek; 28.10.2011
comment
@anatolyg, вы должны уточнить свой вопрос. Что вы хотите сделать, если не узнаете порядок байтов? - person Alexander Oh; 28.10.2011