Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting of arrays in C#

Tags:

arrays

c#

casting

In C# I am working with large arrays of value types. I want to be able to cast arrays of compatible value types, for example:

struct Color
{
    public byte R, G, B, A;
}

Color[] bitmap1 = ...;
uint[] bitmap2 = MagicCast(bitmap1);

I want bitmap2 to share memory with bitmap1 (they have the same bit representations). I don't want to make a copy.

Is there a way to do it?

like image 804
kaalus Avatar asked Aug 01 '14 13:08

kaalus


1 Answers

You can accheive this by using Structlayouts to overlay both arrays. While many answers here wrote how to make the color-struct have a uint aswell, this is about the "array" conversion:

This is evil.

public static class ColorExtension
{
    public static uint[] GetUInts(this Color[] colors)
    {
        if(colors == null) throw new ArgumentNullException("colors");
        Evil e = new Evil { Colors = colors};
        return e.UInts;
    }

    [StructLayout(LayoutKind.Explicit)]
    struct Evil
    {
        [FieldOffset(0)]
        public Color[] Colors;
        [FieldOffset(0)]
        public uint[] UInts;
    }
}

This basically has two Arrays refering the same memory Location.

So If you want to get the array of uints from the array of colors you do it like this:

Color[] colors =  ...

uint[] uints = colors.GetUInts();

As mentioned in the comments, you might need to declare the colorstruct explicitly aswell, or the runtime may fumble arround with the order leading to some "strange" uint values...

[StructLayout(LayoutKind.Sequential)] // Or explicit, but i bellieve Sequential is enough.
struct Color
{
      public byte R;

      public byte G;

      public byte B;

      public byte A;
}

Dont try to debug it though... One of the reasons why this is evil:

like image 143
CSharpie Avatar answered Oct 03 '22 15:10

CSharpie