Инициализировать коллекцию байтов * в C # - PullRequest
3 голосов
/ 25 августа 2010

Мой небезопасный метод принимает коллекцию byte[] с. Все эти byte[] имеют одинаковый размер.

Мне нужно перебрать их все в поисках определенных шаблонов. Поиск по своей сути является интерпретируемым стилем приведения: при каждом смещении мне нужно рассматривать значение, как если бы оно было float, double, short, int и т. Д. Таким образом, получая byte* для каждого ввода byte[] и увеличение его на каждой итерации кажется естественным подходом.

К сожалению, я не могу найти способ создать коллекцию byte* - или, более конкретно, инициализировать ее из коллекции массивов. Есть идеи?

Вот несколько надуманная версия задания:

static unsafe void SearchIteration(List<byte[]> arrays, byte[] resultArr)
{
    fixed (byte* resultFix = resultArr)
    {
        byte* resultPtr = resultFix;
        byte*[] pointers = new byte*[arrays.Count];

        <some code to fix all the arrays and store the pointers in "pointers">

        int remaining = resultArr.Length;
        while (remaining > 0)
        {
            <look at resultPtr and each of the pointers and update *resultPtr>

            remaining--;
            for (int i = 0; i < pointers.Length; i++)
                pointers[i]++;
        }
    }
}

По сути, вопрос заключается в том, как инициализировать pointers с адресами arrays, при этом закрепляя массивы, чтобы GC не перемещал их.

1 Ответ

2 голосов
/ 25 августа 2010

использование GCHandle.Alloc() от System.Runtime.InteropServices:

var handles = new GCHandle[arrays.Count];
byte*[] pointers = new byte*[arrays.Count];
for(int i = 0; i < arrays.Count; ++i)
{
    handles[i] = GCHandle.Alloc(arrays[i], GCHandleType.Pinned);
    pointers[i] = (byte*)handles[i].AddrOfPinnedObject();
}
try
{
    /* process pointers */
}
finally
{
    for(int i = 0; i < arrays.Count; ++i)
    {
        handles[i].Free();
    }
}
...