Как перебрать массив в C # через несколько вызовов - PullRequest
0 голосов
/ 01 декабря 2009

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

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

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

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

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

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

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

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

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

Ответы [ 5 ]

2 голосов
/ 01 декабря 2009

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

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

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

2 голосов
/ 01 декабря 2009

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

0 голосов
/ 01 декабря 2009

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

Stream stream = new MemoryStream(data);

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

0 голосов
/ 01 декабря 2009

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

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

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

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

0 голосов
/ 01 декабря 2009

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

...