Uint32_t байт тәртібін анықтаңыз

Мен vxWorks қосымшасын Linux-ге айналдырып жатырмын.

Бұрын мен struct мүшелеріне қатынасқанда, union мен word және struct struct мүшелерін құрастыру үшін word's макетін қолдануға болар еді.

Алайда, мен оны қалай ойластырғанымды еске түсірмеймін және 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 орналасуын анықтау маңызды.

0
Сұрақ дегеніміз не?
қосылды автор anatolyg, көзі
мұндай нәрсе жасамау керек пе? uint32_t foobar = 0x00ff00ff; егер (((char *) foobar) [0] == 0xff)/* бір endianess */else/* басқа */
қосылды автор Alex, көзі

2 жауаптар

Сіз char мәнін қамтитын int сілтемесін алып, 0x01 мәнін көрсете аласыз. Егер бірінші мән нөлге тең болса, онда жүйе үлкен индиан болып табылады, әйтпесе ол өте аз.

Міне мысал:

#include 
#include 

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-да қолдандым.

3
қосылды
@ 0A0D Сондықтан сіз мұны? мәртебесі x; x.word = 40; printf («% d», x.fields.bytesN);
қосылды автор anatolyg, көзі
Мәселе сіз Status.word қатынасына кірген кезде байттарға кіретін тәртіпті қайтармайсыз. Үлкен Endian (B3, B2, B1, B0) ретінде сақталады, бірақ Little Endian-де бүтін сан B0, B1, B2, B3 түрінде сақталады, яғни Big endian аппараттық құралында ((Status. > ((Status .fields.byteN == 15) && (Status.word == 0x0F000000)), алайда, Үлкен endian платформасының родан ауысқан кезде Status.fields немесе Status.word
қосылды автор David M. Syzdek, көзі
@anatolyg Сіз өзіңіздің сұрағыңызды нақтылауыңыз керек Байт тапсырысын таба алмасаңыз, не істеу керек?
қосылды автор Alex, көзі
Ия, мұны қалай істейтінімді білемін. Бірақ word 40 нөмірін қамтыса, бос емес немесе bytesA емес, бұл сан байтN ішінде. Сондықтан макет маңызды. Арнайы түрде uint32_t қалай жасалады.
қосылды автор user195488, көзі

Сіздің пікіріңізді басқа жауап беруге , сіз кез келген fields.bytesN элементінде пайда болатын union word элементіне толтырылған. Бұл мақсатқа қол жеткізу үшін сізде машиналық индикаторды анықтағаннан кейін өрісі бит өрістерін тиісті түрде дайындайтын алдын ала құрастыру үрдісі болуы керек немесе біреудің екеуі үшін үлкен, ал екіншісіне кішкене индианс жасаңыз.

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 орналасуын пайдаланыңыз.

1
қосылды
тапсырыстың орнын басу.
қосылды автор user195488, көзі
бірақ байтН-ны 31-ге дейін, 23-ке дейін бос қалдырдым, ал байта-1-ге дейін өзгертуім керек болды.
қосылды автор user195488, көзі