0

これは、バイトを含む長い変数を使用するための私のコードですが、プログラムを実行すると例外が発生し、次のように表示されます。

Test.exe で 'System.TypeLoadException' 型の未処理の例外が発生しました

追加情報: アセンブリ 'Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' から型 'Test.MyU32' を読み込めませんでした。オブジェクト フィールド。

[StructLayout(LayoutKind.Explicit)]
public struct MyU32
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public byte[] Bytes;
    [FieldOffset(0)]
    public long Value;
}

対処法を教えてください!

4

3 に答える 3

1

参照と値の型 (64 ビットの int) が重複しているため、コード ケースは機能しません。異なる値の型と異なる参照を重ねることはできますが、それらを混在させることはできません。

しかし、それらが機能する場合でも、そのような低レベルのハックは通常、C# では悪い考えです。低レベルのユニオンではなく、変換を行うプロパティを使用することをお勧めします。

おそらく、あなたが実際に望んでいるのは次のとおりです。

internal static class ByteIntegerConverter
{
    public static UInt32 LoadLittleEndian32(byte[] buf, int offset)
    {
        return
            (UInt32)(buf[offset + 0])
        | (((UInt32)(buf[offset + 1])) << 8)
        | (((UInt32)(buf[offset + 2])) << 16)
        | (((UInt32)(buf[offset + 3])) << 24);
    }

    public static void StoreLittleEndian32(byte[] buf, int offset, UInt32 value)
    {
        buf[offset + 0] = (byte)value;
        buf[offset + 1] = (byte)(value >> 8);
        buf[offset + 2] = (byte)(value >> 16);
        buf[offset + 3] = (byte)(value >> 24);
    }
}

UInt32 value = ByteIntegerConverter.LoadLittleEndian32(buf, offset);
// do something with `value`
ByteIntegerConverter.StoreLittleEndian32(buf, offset, value);

これは、コンピューターのネイティブ エンディアンに関係なく、常にリトル エンディアンを使用します。ネイティブのエンディアンが必要なBitConverter.IsLittleEndian場合は、ビッグ エンディアンの場合は別のシフト定数を確認して使用できます。

于 2013-07-28T11:11:58.573 に答える
0

私は私の問題を解決します

時間を置いたすべてのボディにタンクス。

public struct MyU32
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public byte[] Bytes;
    public uint Value
    {
        get { return ((uint)Bytes[0] + Bytes[1] << 8 + Bytes[2] << 16 + Bytes[3] << 24); }
        set 
        { 
            Bytes[0] = (byte)(value & 0xFF);
            Bytes[1] = (byte)(value>>8 & 0xFF);
            Bytes[2] = (byte)(value>>16 & 0xFF);
            Bytes[3] = (byte)(value>>24 & 0xFF);
        }
    }
}
于 2013-07-28T11:34:58.163 に答える
0

よくわかりませんが、値型と参照型の重複が原因だと思います。値の型のみをオーバーラップできるようにする必要があります。値の型参照の型を重ねることができれば、参照を直接変更できるからです。明らかな安全上の理由から、それは不可能です。

参照型ですbyte[]( .NET のすべての配列と同様) 。重複することはできません。ValueBytes

C に慣れている場合、構造 (明示的なレイアウトなし) は次のように "類似" します。

struct MyU32
{
    byte* Bytes;
    long Value;
}

しかし、それは次のようにはなりません:

struct MyU32
{
    byte Bytes[4];
    long Value;
}
于 2013-07-28T10:58:45.657 に答える