Как перебрать массив в C # через несколько вызовов

StackOverflow https://stackoverflow.com/questions/1823451

  •  22-07-2019
  •  | 
  •  

Вопрос

У нас есть приложение, в котором нам нужно десериализовать некоторые данные из одного потока в несколько объектов.

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

Мы хотим сделать что-то вроде:

void Decode(byte[] Data)  
{  
    Object0.ExtractMessage(Data);
    Object1.ExtractMessage(Data);
    Object2.ExtractMessage(Data);
    ...
}  

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

Чтобы сделать это в C ++, мы просто поместим указатель в массив, и каждая функция ProcessData будет увеличивать его по мере необходимости.

Каждый объектный класс знает, как его собственные сообщения сериализуются, и на него можно положиться (в C ++), чтобы вернуть указатель в начале следующего сообщения в потоке.

Есть ли какой-нибудь встроенный механизм, который мы можем использовать для этого (не делая небезопасным )? Операция высокочастотная (~ 10kps) и очень легкая. Мы также не хотим копировать или обрезать массив.

Спасибо за вашу помощь.

Это было полезно?

Решение

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

Другие советы

Ну, это звучит так, как будто вы хотите простой поток (например, просто используйте MemoryStream в качестве оболочки вокруг вашего байтового массива: stream = new MemoryStream (data)). Просто оберните байтовый массив в поток и каждый объект читает из потока столько, сколько ему нужно, а затем передает поток следующему элементу. Преимущество даже в том, что вам не нужно загружать весь байтовый массив сразу.

Кроме того, вы можете использовать указатели в C # точно так же, как вы это делали в C ++ (хотя для указателей требуется ключевое слово unsafe, и они не поощряются)

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

Как насчет упаковки данных в MemoryStream и последующей передачи StreamReader в метод ExtractMessage?

Я думаю, несколько вещей приходят на ум.

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

Как насчет использования C ++ / CLI? Это позволило бы вам использовать знакомые методы C / C ++, и при этом быть напрямую вызванным из C # без страшного взаимодействия.

Затем, конечно, есть страшная небезопасная опция, при которой вы получаете указатель C # на byte [] и выполняете необходимую арифметику указателя.

Вы можете создать stream из байтового массива.

Stream stream = new MemoryStream(data);

Тогда ваш процессор может работать с потоками.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top