その特定のレイアウトが絶対に必要ですか、それとも単純にサイズ 8 にすることは許容されますか?
レイアウトは次のようになっているので、私はこれを尋ねます
[StructLayout(LayoutKind.Explicit, Size=8)]
public struct SomeStruct
{
[FieldOffset(0)]
public byte SomeByte;
[FieldOffset(1)]
public int SomeInt;
[FieldOffset(5)]
public short SomeShort;
[FieldOffset(7)]
public byte SomeByte2;
}
問題の原因となっている可能性のある、単語が整列されていないフィールドがあります。
物事を「再配置」できる場合、これはうまくいくかもしれません:
[StructLayout(LayoutKind.Explicit, Size=8)]
public struct SomeStruct
{
[FieldOffset(0)]
public byte SomeByte;
[FieldOffset(1)]
public byte SomeByte2;
[FieldOffset(2)]
public short SomeShort;
[FieldOffset(4)]
public int SomeInt;
}
エミュレータでこれをテストすると、正常に動作します。
明らかに、再配置を許可しない限り、あなたにできることは何もありません。
この回答とこの古い記事は、少なくともサイズの倍数で構造体を整列する必要があることを強く示しています(オフセット2に整列されたintで試しましたが、これもエラーを引き起こしました)
外部で定義されたデータと相互運用する必要がある場合、次の方法がおそらく最も簡単な解決策です。
[StructLayout(LayoutKind.Explicit, Size=8)]
public struct SomeStruct
{
[FieldOffset(0)] private byte b0;
[FieldOffset(1)] private byte b1;
[FieldOffset(2)] private byte b2;
[FieldOffset(3)] private byte b3;
[FieldOffset(4)] private byte b4;
[FieldOffset(5)] private byte b5;
[FieldOffset(6)] private byte b6;
[FieldOffset(7)] private byte b7;
// not thread safe - alter accordingly if that is a requirement
private readonly static byte[] scratch = new byte[4];
public byte SomeByte
{
get { return b0; }
set { b0 = value; }
}
public int SomeInt
{
get
{
// get the right endianess for your system this is just an example!
scratch[0] = b1;
scratch[1] = b2;
scratch[2] = b3;
scratch[3] = b4;
return BitConverter.ToInt32(scratch, 0);
}
}
public short SomeShort
{
get
{
// get the right endianess for your system this is just an example!
scratch[0] = b5;
scratch[1] = b6;
return BitConverter.ToInt16(scratch, 0);
}
}
public byte SomeByte2
{
get { return b7; }
set { b7 = value; }
}
}