Преобразование Endianess на небольшой полевой структуре

Воспроизводите вашу проблему на моей стороне всегда.

enter image description here

Обратите внимание, что исключение вызвано следующим методом:

enter image description here [1112 ]

Попробуйте десериализовать исходный код DLL и найти подробный логический код.

enter image description here

Кажется, мы пока не можем пересмотреть это суждение, потому что команда cosmos db планирует отказаться от возможности создавать неразделенные контейнеры, так как они не позволяют вам эластично масштабировать. (Упомянутое в моем предыдущем случае: Это все еще хорошая идея - создать коллекцию comos db без ключа раздела?

. многораздельные контейнеры с DocumentDB .net пакетом или REST API .

7
задан starblue 17 June 2009 в 15:40
поделиться

7 ответов

Для этого я наконец-то нашел решение (кое-что полученное из решения эпателя выше). Это если я преобразую из x86 в Solaris SPARC.

Нам нужно сначала поменять местами входящую структуру, а затем прочитать элементы в обратном порядке. В основном, посмотрев на выравнивание структур, я увидел, что порядок байтов изменился как в порядке следования байтов, так и в порядке следования битов. Вот псевдокод.

struct orig
{    
    unsigned int    b1:1;
    unsigned int    b2:8;
    unsigned int    b3:7;
    unsigned int    b4:8;
    unsigned int    b5:7;
    unsigned int    b6:1;
};

struct temp
{    
    unsigned int    b6:1;
    unsigned int    b5:7;
    unsigned int    b4:8;
    unsigned int    b3:7;
    unsigned int    b2:8;
    unsigned int    b1:1;
}temp;


func (struct orig *toconvert)
{
    struct temp temp_val;
    //Swap the bytes
    swap32byte((u32*)toconvert);
    //Now read the structure in reverse order - bytes have been swapped
    (u32*)&temp_val = (u32 *)toconvert;
    //Write it back to orignal structure
    toconvert->b6=temp_val.b6;
    toconvert->b5=temp_val.b5;
    toconvert->b4=temp_val.b4;
    toconvert->b3=temp_val.b3;
    toconvert->b2=temp_val.b2;
    toconvert->b1=temp_val.b1;

}

После некоторых экспериментов я обнаружил, что этот подход действителен, только если элементы полностью заполняют структуру, то есть нет неиспользуемых битов.

-3
ответ дан 6 December 2019 в 10:53
поделиться

Вы могли использовать целое число на 32 бита и извлечь информацию из нее использование и - и операторы сдвига разряда. С этим на месте, Вы могли просто использовать htonl (хост сети, долго). Сетевой порядок байтов является обратным порядком байтов.

Это не будет столь же изящно как битовое поле, но по крайней мере Вы будете знать то, что Вы имеете и не должны будете волновать по поводу компилятора, дополняющего Ваши структуры.

8
ответ дан 6 December 2019 в 10:53
поделиться

В проекте, портирующем код от MIPS до Linux/x86, нам действительно нравилось это.

struct {

#ifdef __ONE_ENDIANESS__
    unsigned int    b1:1;
    unsigned int    b2:8;
    unsigned int    b3:7;
    unsigned int    b4:8;
    unsigned int    b5:7;
    unsigned int    b6:1;
#define _STRUCT_FILLED
#endif /* __ONE_ENDIANESS__ */

#ifdef __OTHER_ENDIANESS__
    unsigned int    b6:1;
    unsigned int    b5:7;
    unsigned int    b4:8;
    unsigned int    b3:7;
    unsigned int    b2:8;
    unsigned int    b1:1;
#define _STRUCT_FILLED
#endif /* __OTHER_ENDIANESS__ */

};

#ifndef _STRUCT_FILLED
#  error Endianess uncertain for struct
#else
#  undef _STRUCT_FILLED
#endif /* _STRUCT_FILLED */

Макросы __ONE_ENDIANESS__ и __OTHER_ENDIANESS__ если бы подходящее был для компилятора, который мы использовали так, то Вы, возможно, должны были бы изучить, который подходит для Вас...

5
ответ дан 6 December 2019 в 10:53
поделиться

Вы хотите сделать это между каналом (файл или сеть) и Вашей структурой. Моя предпочтительная практика должна изолировать файловый ввод-вывод от структур, пишут код, который создает буферы файлов в известном представлении и соответствие прочитанному коду, который инвертирует то преобразование.

Ваш определенный пример особенно трудно предположить, потому что битовые поля определяются, чтобы быть неподписанным интервалом и sizeof(unsigned int) является особенно непортативным.

Принятие как ДОБЫЧА это sizeof(int)==4 затем получая указатель на структуру и reording отдельные байты, вероятно, получают Вас ответ, который Вы хотите.

Прием определения структуры по-другому для различных платформ мог бы работать, но в примере Вы цитируете нет полного разрыва на границах байта, таким образом, вряд ли будет возможно произвести эквивалент одной платформы в другом, не разделяя один или несколько полей в две части.

1
ответ дан 6 December 2019 в 10:53
поделиться

Должно быть достаточно подкачать байты. Позиция двоичного разряда в байте является тем же в и прямом порядке байтов с обратным порядком байтов.
например:

char* dest = (char*)&yourstruct;
unsigned int orig = yourstruct;
char* origbytes = (char*)&orig;
dest[0] = origbytes[3];
dest[1] = origbytes[2];
dest[2] = origbytes[1];
dest[3] = origbytes[0];
0
ответ дан 6 December 2019 в 10:53
поделиться

У Вас есть два раздела на 16 битов там (первые три поля, и последние три поля составляют 16 битов).

Это - только 65 536 записей. Поэтому имейте справочную таблицу, которая содержит инвертированную битом версию полей. Перенесите структуру в объединение с другой структурой, которая имеет два 16 битовых полей для создания этого легче?

Что-то как (непротестированный, я не около компилятора C):

union u {
    struct {
        unsigned int    b1:1;
        unsigned int    b2:8;
        unsigned int    b3:7;
        unsigned int    b4:8;
        unsigned int    b5:7;
        unsigned int    b6:1;
     } bits;
     struct {
        uint16 first;
        uint16 second;
     } words
} ;

unit16 lookup[65536];

/* swap architectures */

void swapbits ( union u *p)
{
   p->words.first = lookup[p->words.first];
   p->words.second = lookup[p->words.second];
}

Население справочной таблицы, оставленной как осуществление для читателя :)

Однако прочитайте свой документ компилятора тщательно. Я не уверен, требует ли стандарт C, что структура для установки, одним словом (хотя я ожидал бы, что большинство компиляторов сделает это).

1
ответ дан 6 December 2019 в 10:53
поделиться

Не следует использовать битовые поля, когда важен физический макет, поскольку он определяется реализацией, в каком порядке больший слово заполнено.

0
ответ дан 6 December 2019 в 10:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: