Search code examples
c#arraysstringunsafe

Convert fixed size buffer (byte array) to string


I've seen several related topics on SO and other forums, but haven't found a workable answer to my question.

Here's my code:

[StructLayout(LayoutKind.Explicit, Size = 128)]
internal unsafe struct Frame
{
    [FieldOffset(0)]
    public fixed byte Bytes[128];

    [FieldOffset(0)]
    public long Low;

    [FieldOffset(128 - sizeof(long))]
    public long High;
}

unsafe private void button32_Click(object sender, EventArgs e)
{
    Frame frame;

    // ERROR: Error 15  You cannot use the fixed statement to take the address of an already fixed expression
    fixed (byte* ptr = frame.Bytes)
    {

    }

    // ERROR
    Console.Write(System.Text.Encoding.ASCII.GetString(frame.Bytes, 0, 128));
    frame.Low = 1234;
    //Console.Write(System.Text.Encoding.ASCII.GetString(frame.Bytes));
    frame.High = 5678;
    //Console.Write(System.Text.Encoding.ASCII.GetString(frame.Bytes));
}

Solution

  • Just wrap the struct into another class to eliminate the fixed pointer issue. This creates the struct inside the memory frame of the new class. Then convert the fixed array to a byte[] to eliminate the GetString() issue. Maybe this helps?

    namespace test
    {
            [StructLayout(LayoutKind.Explicit, Size = 128)]
            internal unsafe struct Frame
            {
                [FieldOffset(0)]
                public fixed byte Bytes[128];
    
                [FieldOffset(0)]
                public long Low;
    
                [FieldOffset(128 - sizeof(long))]
                public long High;                
            }
    
        internal class NewClass
        {
            public Frame FixedBytesArray;
        }
    
        internal class Program
        {
            static void Main(string[] args)
            {
                unsafe
                {
                    NewClass NewType = new NewClass();
                    NewType.FixedBytesArray.High = 12345;
                    NewType.FixedBytesArray.Low = 6789;
    
    
                    fixed (byte* ptr = NewType.FixedBytesArray.Bytes)
                    {
                        byte[] bytes = new byte[128];
                        int index = 0;
                        for (byte* counter = ptr; *counter != 0; counter++)
                        {
                            bytes[index++] = *counter;
                        }
    
                        Console.Write(System.Text.Encoding.ASCII.GetString(bytes, 0, 128));
                    }
                }    
            }
        }
    }