Порядок байтов действительно ли C# чувствителен?

C# когда-либо, чувствительный Порядок байтов, например, кодирует, такие как это:

int a = 1234567;
short b = *(short*)&i;

всегда присваивайте то же значение b. Если так, каково значение это будет?

В противном случае, в чем хорошие пути там состоят в том, чтобы иметь дело с порядком байтов если код с указателями?

12
задан Martin 11 February 2010 в 21:37
поделиться

4 ответа

C # не определяет порядок байтов. На самом деле да, вероятно, он всегда будет прямым порядком байтов (IIRC даже на IA64, но я не проверял), но в идеале вы должны проверить BitConverter.IsLittleEndian , если порядок байтов важен - или просто используйте битовый смещение и т. д., а не прямой доступ к памяти.

Процитируем несколько строк из protobuf-net (сборка еще не зафиксирована):

WriteInt64(*(long*)&value);
if (!BitConverter.IsLittleEndian)
{   // not fully tested, but this *should* work
    Reverse(ioBuffer, ioIndex - 8, 8);
}

т.е. он проверяет порядок байтов и при необходимости выполняет обратное преобразование.

15
ответ дан 2 December 2019 в 18:54
поделиться

На самом деле, вам не следует переключаться указателями на языке C #. Необходимо попытаться скомпилировать код, прежде чем спрашивать, что он будет делать.

-121--2818454-

C # не определяет зависимость. На самом деле, да, это, вероятно, всегда будет little-endian (IIRC даже на IA64, но я не проверял), но вы должны идеально проверить BitConverter.IsLittleEndian , если эндианния важна - или просто использовать bit-shifting и т.д., а не прямой доступ к памяти.

Процитировать несколько строк из protobuf-net (сборка еще не зафиксирована):

WriteInt64(*(long*)&value);
if (!BitConverter.IsLittleEndian)
{   // not fully tested, but this *should* work
    Reverse(ioBuffer, ioIndex - 8, 8);
}

т. е. он проверяет эндианнесс и при необходимости выполняет флип.

-121--2818450-

Да, я считаю, что код является чувствительным к эндии. Значение b будет наименее значимыми байтами на малозначительном процессоре и наиболее значимыми байтами на биг-эндийном процессоре. Чтобы это было проще увидеть, давайте перейдем к шестнадцатеричному:

using System;

class Test
{
    unsafe static void Main()
    {
        int a = 0x12345678;
        short b = *(short*)&a;
        Console.WriteLine(b.ToString("x"));
    }
}

На моем поле x86 будет напечатано «5678», показывающее, что наименее значимые байты находятся в «начале» значения a . Если вы используете тот же код на процессоре, работающем в режиме big-endian (вероятно, под Mono), я бы ожидал, что он напечатает «1234».

6
ответ дан 2 December 2019 в 18:54
поделиться

Насколько я могу судить, ни в C #, ни в спецификациях Common Language Infrastructure нет требований к порядку байтов для побитовых и математических операций на основе указателей. В интерфейсе командной строки указано, что двоичные данные, хранящиеся в исполняемом файле MSIL, должны иметь формат с прямым порядком байтов.И общий сдвиг документов будет указывать на то, что код не должен зависеть от какого-либо конкретного представления памяти (включая упакованные или распакованные массивы и т. Д.), За исключением особых обстоятельств.

1
ответ дан 2 December 2019 в 18:54
поделиться

Вам действительно не следует делать смену указателей на C #. Вам следует попробовать скомпилировать свой код, прежде чем спрашивать, что он будет делать.

-3
ответ дан 2 December 2019 в 18:54
поделиться
Другие вопросы по тегам:

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