StructLayoutとFieldOffset属性 - C#

属性を学んでいてなかなかおもしろいなぁと感じたのでメモる。
StructLayoutFieldOffsetを使用すると便利なモノができるようだ。


StructLayout - クラスまたは構造体のデータ フィールドの物理的なレイアウトを制御できる。
FieldOffset - フィールドの物理的な位置を示す。

StructLayout属性でレイアウトの種類を指定して、FieldOffset属性で先頭からの距離をバイト単位で指定することになる。
下記の例ではbyte型のAlphaRedGreenBlueの計4つのフィールド、つまり4バイトの構造体を作成している。

[StructLayout(LayoutKind.Explicit)]
struct ARGBColor
{
    [FieldOffset(3)] public byte Alpha;
    [FieldOffset(2)] public byte Red;
    [FieldOffset(1)] public byte Green;
    [FieldOffset(0)] public byte Blue;
    [FieldOffset(0)] public uint Argb;
}
AlphaRedGreenBlueフィールドでは1バイトのデータにアクセスする。
Argbフィールドでは4バイトのデータにアクセスする。

Argbに値を設定するとAlphaRedGreenBlueのそれぞれに値が設定される。
またその逆にAlphaRedGreenBlueのそれぞれに値を設定するとArgb値も当然変化する。

すごく便利だ(^-^)

欲を言えば、public int Rgbとして、Alphaを省いたRGB値も取得できたらもっと良かったのだが、どうもうまくいかない(-_-;)

色を16進数で表す場合「ARGB」つまり、「AlphaRedGreenBlue」の順番となるので、FieldOffset属性に設定する値でその順番を間違えないように気を付けたい。


Example
ARGBColor color = new ARGBColor();
color.Argb = 0x8033ff;

FieldInfo[] fields = color.GetType()
    .GetFields(BindingFlags.Instance | BindingFlags.Public);

Console.WriteLine("{0,-6} {1,12}{2,12}", "Name", "hex", "int");
foreach (FieldInfo field in fields)
{
    Console.WriteLine("{0,-6}:{1,12}{2,12}",
        field.Name,
        Convert.ToString(Convert.ToInt64(field.GetValue(color)), 16),
        field.GetValue(color));
}

color.Alpha = 0xff;
color.Red = 0x33;
color.Green = 0x66;
color.Blue = 0x99;

Console.WriteLine("\n{0,-6} {1,12}{2,12}", "Name", "hex", "int");
foreach (FieldInfo field in fields)
{
    Console.WriteLine("{0,-6}:{1,12}{2,12}",
        field.Name,
        Convert.ToString(Convert.ToInt64(field.GetValue(color)), 16),
        field.GetValue(color));
}

Output
Name            hex         int
Alpha :           0           0
Red   :          80         128
Green :          33          51
Blue  :          ff         255
Argb  :      8033ff     8401919

Name            hex         int
Alpha :          ff         255
Red   :          33          51
Green :          66         102
Blue  :          99         153
Argb  :    ff336699  4281558681

0 Comments:

Sony Style(ソニースタイル)
デル株式会社

Recent Posts