How to access allocated memory as either an array of shorts or an array of bytes

RHaggard

New member
Joined
Sep 29, 2019
Messages
2
Programming Experience
10+
A C# application needs to allocate memory and treat that block as either an array of bytes or an array of shorts.

Here's what I've tried. A structure was declared that was supposed to have a byte[] and a short[] occupying the same memory space.
C#:
        [StructLayout(LayoutKind.Explicit)]
        struct ByteToShortArray
        {
            [FieldOffset(0)]
            public byte[] bytes;

            [FieldOffset(0)]
            public short[] shorts;
        }
At run time, the amount of memory that would be required in terms of bytes is determined and allocated. The structure is loaded with that memory block.
C#:
ByteToShortArray byteToShortArray = new ByteToShortArray();
buffer = new byte[acquisitionSize];
byteToShortArray.bytes = buffer;
The above mechanism fails in that the bytes member appears to share the low byte of the shorts member that shares the same index. If 256 bytes are allocated there are also 256 shorts is is not what we want. The expectation is that each shorts member would share union data with the bytes array members whose indexes are [n/2] and [n/2+].

As an example, if bytes[5] is 0xe0, bytes[10] is 0x11 and bytes[11] is 0x22 then shorts[5] should be 0x2211. It is not. It is 0xe0.

Any suggestions on how to accomplish this?
 
Last edited by a moderator:

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,122
Location
Chesapeake, VA
Programming Experience
10+
If you are willing to use unsafe keyword and compile with the /UNSAFE flag, the easiest solution is simply use pointers.
 

JohnH

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
1,183
Location
Norway
Programming Experience
10+
What if you add an indexed property and convert? BitConverter uses unsafe code and pointers to convert the value.
C#:
public short this[int index]
{
    get { return BitConverter.ToInt16(bytes, index * 2); }
    set { BitConverter.GetBytes(value).CopyTo(bytes, index * 2); }
}
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,122
Location
Chesapeake, VA
Programming Experience
10+
In my Blake3 .NET Standard implementation, I had to switch between bytes and uints often, so I had these extension methods which are simple wrappers around the MemoryMarshal methods.

 
Top Bottom