Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Byte order в .NET

723
03 сентября 2006 года
Tommy
78 / / 13.10.2002
Снова вопрос относящийся к реализации протокола. Значит, если в протоколе некоторые поля с прямым порядком байтов, то единственный извесный путь для меня это просто тупо менять их порядок. Есть-ли какая-то возможность сделать эту операцию все-таки более инкапсулированной, если так можно выразиться. То есть указать порядок байт. То есть либо в существует такой атрибут, либо создать свой но тогда надо знать какой порядок байт используеться в текущей системе (во время исполнения).
273
04 сентября 2006 года
3A3-968M
1.2K / / 22.12.2005
Прямой или обратный порядок - это уже абстракция, т.к. для машины по большому счёту всё равно. Показываю пример, как получить структуру в прямом и обратном порядке разбора байт:
Код:
[SIZE=2][FONT=Courier New][[/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]StructLayout[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#008080]LayoutKind[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].Sequential)][/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]struct [/COLOR][/SIZE][SIZE=2][COLOR=#008080]MyStruct
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]{[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] Field1;[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]ushort[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] Field2;[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]byte[/COLOR][/SIZE][SIZE=2][] ToArray([/SIZE][SIZE=2][COLOR=#008080]ByteOrder[/COLOR][/SIZE][SIZE=2] order) [/SIZE][SIZE=2][COLOR=#008000]//превратить структуру в массив байтов
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]  {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    int[/COLOR][/SIZE][SIZE=2] size = [/SIZE][SIZE=2][COLOR=#008080]Marshal[/COLOR][/SIZE][SIZE=2].SizeOf([/SIZE][SIZE=2][COLOR=#0000ff]this[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    byte[/COLOR][/SIZE][SIZE=2][] result = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]byte[/COLOR][/SIZE][SIZE=2][size]; [/SIZE][SIZE=2][COLOR=#008000]//выделить managed память
[/COLOR][/SIZE][/FONT][SIZE=2][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]    IntPtr[/COLOR][/SIZE][SIZE=2] pThis = [/SIZE][SIZE=2][COLOR=#008080]Marshal[/COLOR][/SIZE][SIZE=2].AllocHGlobal(size); [/SIZE][SIZE=2][COLOR=#008000]//выделить unmanaged память
[/COLOR][/SIZE][/FONT][SIZE=2][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]    Marshal[/COLOR][/SIZE][SIZE=2].StructureToPtr([/SIZE][SIZE=2][COLOR=#0000ff]this[/COLOR][/SIZE][SIZE=2], pThis, [/SIZE][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    for[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] i = 0; i < size; i++)[/FONT]
[FONT=Courier New]      result = [/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]Marshal[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].ReadByte(pThis, i);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    if[/COLOR][/SIZE][SIZE=2] (order == [/SIZE][SIZE=2][COLOR=#008080]ByteOrder[/COLOR][/SIZE][SIZE=2].RightToLeft) [/SIZE][SIZE=2][COLOR=#008080]Array[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].Reverse(result); [/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]    Marshal[/COLOR][/SIZE][SIZE=2].FreeHGlobal(pThis); [/SIZE][SIZE=2][COLOR=#008000]//очистить unmanaged память
[/COLOR][/SIZE][/FONT][SIZE=2][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    return[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] result;[/FONT]
[FONT=Courier New]  }[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]  public [/COLOR][/SIZE][SIZE=2][COLOR=#008080]MyStruct[/COLOR][/SIZE][SIZE=2] ChangeOrder([/SIZE][SIZE=2][COLOR=#008080]ByteOrder[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] order)[/FONT]
[FONT=Courier New]  {[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    object[/COLOR][/SIZE][SIZE=2] ms = [/SIZE][SIZE=2][COLOR=#0000ff]default[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#008080]MyStruct[/COLOR][/SIZE][SIZE=2]); [/SIZE][SIZE=2][COLOR=#008000]//создаём структуру
[/COLOR][/SIZE][/FONT][SIZE=2][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    byte[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New][] array = ToArray(order);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    for[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] i = 0; i < array.Length; i++) [/SIZE][SIZE=2][COLOR=#008000]//меняем порядок байт
[/COLOR][/SIZE][/FONT][SIZE=2][/SIZE][FONT=Courier New][SIZE=2][COLOR=#008080]      Marshal[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New].WriteByte(ms, i, array);[/FONT]
[/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]    return[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#008080]MyStruct[/COLOR][/SIZE][SIZE=2])ms; [/SIZE][SIZE=2][COLOR=#008000]//unboxing
[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New]  }[/FONT]
[FONT=Courier New]}[/FONT]
[/SIZE]

Метод ToArray превращает экземпляр структуры в массив байтов, т.е. все поля представляются в виде неделимого блока байт. Тип ByteOrder означает порядок байт. Как видишь, очень легко менять порядок байт если тебе нужно. Метод ChangeOrder меняет порядок байт структуры.
273
04 сентября 2006 года
3A3-968M
1.2K / / 22.12.2005
Тип ByteOrder описал так:
 
Код:
[SIZE=2][COLOR=#0000ff][FONT=Courier New]public [/FONT][/COLOR][/SIZE][FONT=Fixedsys][FONT=Courier New][SIZE=2][COLOR=#0000ff]enum [/COLOR][/SIZE][SIZE=2][COLOR=#008080]ByteOrder[/COLOR][/SIZE][SIZE=2] : [/SIZE][SIZE=2][COLOR=#0000ff]byte[/COLOR][/SIZE][SIZE=2] {LeftToRight, RightToLeft}
[/SIZE][/FONT][/FONT]
723
04 сентября 2006 года
Tommy
78 / / 13.10.2002
Вот чего я хотел:
 
Код:
struct
    {
         byte id;
         [ByteOrder(Big-Endian)]
         Uint16 xxx;
         // Или MyInt

    }


И теперь если я присваиваю xxx значение тогда в память он записывает в прямом порядке, и когда я отправляю это посети всё верно, но если вдруг оказываеться что на текущей машине используеться прямой порядок байт то тот атрибут должен знать это и не емнять никакго порядка. Вот. То есть в сеть нужно отправлять байты с известным порядком байт а на машине он неизвестен.
273
08 сентября 2006 года
3A3-968M
1.2K / / 22.12.2005
На всех аппаратных платформах, где есть .NET, порядок байт одинаковый, так что не парься. Или что мешает тебе использовать управляемый массив byte[].
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог