47

次のコードを検討してください。

public enum MyEnum { V1, V2, V3 }

int size = Marshal.SizeOf(typeof(MyEnum));

それは例外をスローします:

タイプ 'System.ArgumentException' の未処理の例外が TestConsole.exe で発生しました

追加情報: タイプ 'TestConsole.Program+MyEnum' は、アンマネージ構造としてマーシャリングできません。意味のあるサイズまたはオフセットを計算できません。

このコードは例外をスローせず、size4 が含まれていますが、

public enum MyEnum { V1, V2, V3 }

public struct MyStruct
{
    public MyEnum en;
}

int size = Marshal.SizeOf(typeof(MyStruct));

enum最初のサンプル コードで .NET フレームワークが 4 バイトであることを認識できない理由を誰か説明できますか?

アップデート

Marshal.Sizeof()この一般的な方法で失敗しました:

public bool IoControlReadExact<T>(uint ioControlCode, out T output) where T : struct
{
    output = new T();

    int outBufferSize = Marshal.SizeOf(typeof(T));
    IntPtr outBuffer = Marshal.AllocHGlobal(outBufferSize);
    if (outBuffer == IntPtr.Zero)
        return false;
    try
    {
        uint bytesReturned;
        return IoControlRead(ioControlCode, outBuffer, (uint)outBufferSize, out bytesReturned) && ((uint)outBufferSize == bytesReturned);
    }
    finally
    {
        output = (T)Marshal.PtrToStructure(outBuffer, typeof(T));
        Marshal.FreeHGlobal(outBuffer);
    }
}

そして、コンパイラenumstruct.

解決

ジェネリック メソッドをリファクタリングして、 と の両方で機能させることができstructますenum

// determine the correct output type:
Type outputType = typeof(T).IsEnum ? Enum.GetUnderlyingType(typeof(T)) : typeof(T);
//...
int outBufferSize = Marshal.SizeOf(outputType);
//...
output = (T)Marshal.PtrToStructure(outBuffer, outputType);
4

2 に答える 2