簡體   English   中英

編組結構與類的數組

[英]Marshalling array of structs vs classes

我想使用編組將本機結構讀入C#類型。 我對Marshal結構的方法是這樣的:

T ReadObject<T>(BinaryReader br) {
    var bytes = br.ReadBytes(Marshal.SizeOf(typeof(T)));
    var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    try {
        return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
    }
    finally {
        handle.Free();
    }
}

現在這一般工作正常,問題出現在以下類型:

[StructLayout(LayoutKind.Sequential, Pack=1)]
class SubData {
    public short A1;
    public short A2;
}

[StructLayout(LayoutKind.Sequential, Pack=1)]
class Data {
    public short Id;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
    public SubData[] SubDatas;
}

請注意, 如果SubData是一個結構這可以正常工作 但是如果SubData是一個類,它會導致Marshal.PtrToStructure拋出FatalExecutionEngineError。 我想堅持使用類,因為有時候我的類型有默認值,結構不能有字段初始化器和默認構造函數,而且其中一些類型相當大。

謝謝您的幫助。

編輯:錯誤消息是“運行時遇到致命錯誤。錯誤的地址是0x6af99aec,在線程0x348。錯誤代碼是0xc0000005。此錯誤可能是CLR中的錯誤或不安全或非錯誤用戶代碼的可驗證部分。此錯誤的常見來源包括COM-interop或PInvoke的用戶封送錯誤,這可能會破壞堆棧。“

類是引用類型,因此當使用Marshal.PtrToStructure時,它將復制指針,而Subdata的位置則沒有值。
將Subdata聲明為struct時,將復制子數據的實際值。
因此,在進行編組時,必須使用結構。 您可能仍然有一個類,它將在構造函數中使用struct版本。
你可以通過使用來證明這一點

的sizeof

看到尺寸會有所不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM