2

次の構造体にマーシャリングする必要があるバイト配列があります。

[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct ACSEventHeader_t
{
    public UInt32 acsHandle;
    public EventClasses eventClass;
    public UInt16 eventType;
};

EventClasses 列挙は次のように定義されます。

internal enum EventClasses
{
    Request = 0,
    Unsolicited = 1,
    ConnectionConfirmation = 2,
    CommandConfirmation = 5
}

これを行うために使用するコードは次のようになります (eventBuf.Data は byte[] 型です)。

ACSEventHeader_t h = new ACSEventHeader_t();
IntPtr pt1 = Marshal.AllocHGlobal(eventBuf.Data.Length);
Marshal.Copy(eventBuf.Data, 0, pt1, eventBuf.Data.Length);
h = (ACSEventHeader_t)Marshal.PtrToStructure(pt1, typeof(ACSEventHeader_t));
Marshal.FreeHGlobal(pt1);

コードがそのままの状態でこれを行うと、例外なく機能しますが、ACSEventHeader_t 構造体の eventClass プロパティの値が正しくありません。タイプを UInt16 に変更すると正しい値が得られますが、列挙型がありません。

[MarshalAs(UnmanagedType.U2)] を eventClass プロパティに追加しようとしましたが、次の例外が発生します。

Cannot marshal field 'eventClass' of type 'ACSEventHeader_t': 
enter code here`Invalid managed/unmanaged type combination (Int32/UInt32 must be
paired with I4, U4, or Error).

どんな助けでも大歓迎です...

4

1 に答える 1

8

宣言する方法を変更するだけですenum:

internal enum EventClasses : short
{
    Request = 0,
    Unsolicited = 1,
    ConnectionConfirmation = 2,
    CommandConfirmation = 5
}

デフォルトでenumは s は typeInt32ですが、それらのタイプを必要なものに明示的に設定できます。

于 2012-07-06T10:03:26.110 に答える