C# byte array to fixed int pointer

13,454

Solution 1

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
    }
}

Solution 2

I believe you have to go via a byte*. For example:

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
        }
    }
}

Note that when iterating, you should use rawData.Length / 4, not rawData.Length if you're treating your byte array as a sequence of 32-bit values.

Solution 3

I found a - seemingly - more elegant and for some reason also faster way of doing this:

        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();

This way the only thing i need to do - apart from setting the correct iteration length - is increment the pointer. I compared the code with the one using the fixed statement, and this one is slightly faster.

Share:
13,454
WhiteN01se
Author by

WhiteN01se

Updated on June 25, 2022

Comments

  • WhiteN01se
    WhiteN01se almost 2 years

    is it possible to somehow cast the type of a pointer created by the fixed() statement?

    This is the situation:

    I have an array of byte, which i would like to iterate through, however i would like the values to be treated as int, thus having an int* instead of a byte*.

    Here's some exemplary code:

    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
        }
    }
    

    Can this be done without having to do the cast inside the iteration?

  • Guvante
    Guvante over 12 years
    You aren't actually moving your pointer, would probably be a good idea to show that. You should also mention the difference in byte size.
  • Quick Joe Smith
    Quick Joe Smith about 12 years
    What is the best way to process any remaining bytes with pointer arithmetic that do not divide evenly into sizeof(int)? (For example, if the byte array was 1023 bytes long.)
  • Jon Skeet
    Jon Skeet about 12 years
    @QuickJoeSmith: I'd probably handle those not with pointer arithmetic, basically.