C # байтовый массив для фиксированного указателя int - PullRequest
4 голосов
/ 17 января 2012

возможно ли как-то привести тип указателя, созданного оператором fixed ()?

Это ситуация:

У меня есть массив байтов, который я хотел быдля итерации, однако мне бы хотелось, чтобы значения обрабатывались как int, поэтому вместо байта должен быть int *.

Вот примерный код:

byte[] rawdata = new byte[1024];

fixed(int* ptr = rawdata) //this fails with an implicit cast error
{
    for(int i = idx; i < rawdata.Length; i++)
    {
        //do some work here
    }
}

Может ли это бытьсделано без необходимости выполнять приведение внутри итерации?

Ответы [ 3 ]

5 голосов
/ 17 января 2012

Я считаю, что вам нужно пройти через a byte*.Например:

using System;

class Test
{
    unsafe static void Main()
    {
        byte[] rawData = new byte[1024];
        rawData[0] = 1;
        rawData[1] = 2;

        fixed (byte* bytePtr = rawData)
        {
            int* intPtr = (int*) bytePtr;
            Console.WriteLine(intPtr[0]); // Prints 513 on my box
        }
    }
}

Обратите внимание, что при итерации следует использовать rawData.Length / 4, а не rawData.Length, если вы обрабатываете свой байтовый массив как последовательность 32-битных значений.

4 голосов
/ 17 января 2012
byte[] rawdata = new byte[1024];

fixed(byte* bptr = rawdata)
{
    int* ptr=(int*)bptr;
    for(int i = idx; i < rawdata.Length; i++)
    {
        //do some work here
    }
}
2 голосов
/ 19 января 2012

Я нашел - казалось бы - более элегантный и по какой-то причине более быстрый способ сделать это:

        byte[] rawData = new byte[1024];
        GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
        int* iPtr = (int*)rawDataHandle.AddrOfPinnedObject().ToPointer();
        int length = rawData.Length / sizeof (int);

        for (int idx = 0; idx < length; idx++, iPtr++)
        {
            (*iPtr) = idx;
            Console.WriteLine("Value of integer at pointer position: {0}", (*iPtr));
        }
        rawDataHandle.Free();

Таким образом, единственное, что мне нужно сделать - кроме установки правильной длины итерации - это увеличить указатель. Я сравнил код с кодом, использующим оператор fixed, и этот код немного быстрее.

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