Отображение структур на память в C #, стоит ли это того?Или есть лучший способ - PullRequest
0 голосов
/ 04 июня 2011

Я отправляю несколько пакетов данных по сети, и они поступают в байтах [], скажем, структура

[int, int, byte, int]

Если бы это был c ++, я бы объявил структуру * и указал бы на байт []. Я делаю этот проект в C #, и я не уверен, стоит ли он того, чтобы выполнить маршаллинг, или есть лучший способ справиться с ним в C #, я весь слух

  • обновление, для наглядности

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

Ответы [ 4 ]

0 голосов
/ 08 июня 2011

В качестве альтернативы BitConverter, оберните каждый byte[] в MemoryStream и извлеките поля, используя BinaryReader.Аналогично, но поток поддерживает смещения для вас.

0 голосов
/ 04 июня 2011

Единственная реальная причина сделать это таким образом - выжать из системы все до последней части. На мой взгляд, вам лучше написать его, используя BitConverter, чтобы убедиться, что он работает. Затем, если получение данных является узким местом в производительности, рассмотрите возможность маршалинга.

Например, с учетом структуры:

struct MyStruct
{
    private int f1;
    private int f2;
    private byte f3;
    private int f4;
    public MyStruct(int i1, int i2, byte b1, int i4)
    {
        f1 = i1;
        f2 = i2;
        f3 = b1;
        f4 = i4;
    }
    // assume there are public get accessors
}

Затем вы можете создать новый из буфера с помощью:

var s = new MyStruct(BitConverter.ToInt32(buff, 0),
    BitConverter.ToInt32(buff, 4),
    BitConverter.ToUInt8(buff, 8),
    BitConverter.ToInt32(buff, 9));

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

0 голосов
/ 04 июня 2011

Ну, я думаю, у каждого свой «любимый» путь.При получении протокольных единиц через поток байтов на любом языке OO я обычно запускаю каждый полученный байт в экземпляр класса ProtocolUnit, вызывая его метод bool addByte ().Конечный автомат в классе обрабатывает байты, а ошибка / здравый смысл проверяет собранные поля.Если ProtocolUnit был получен полностью, функция метода addByte () возвращает true, чтобы указать вызывающей стороне, что PDU был правильно собран.Обычно экземпляр затем ставится в очередь, чтобы обработать его, и создается новый ProtocolUnit (или удаляется), поэтому он может начать сборку следующего PDU.

Подразумевается, что начало сообщенияможет быть идентифицирован таким образом, чтобы в случае ошибки конечный автомат мог либо сам себя сбросить, сбросив ошибочные данные, либо вернув true в вызове addByte (), установив подходящий errorMessage, который вызывающий может проверитьрешить, что делать, (например, если свойство errorMess равно "", то очередь к обработчику, иначе очередь к журналу ошибок).

Я уверен, что вы считаете это огромным излишним, но это работает для меня:)

Rgds, Martin

PS старайтесь избегать протоколов, в которых длина передается в начале и является единственным способом определения начала / конца сообщения.Это очень хрупко и подвержено взрывам, особенно с незащищенными транспортными средствами, такими как UDP.Даже с TCP я знаю маршрутизатор ax **** x, который иногда добавляет к пакетам ноль ...

0 голосов
/ 04 июня 2011

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

...