2012-03-27 58 views
4

我想使用編組將一個本地結構讀入C#類型。我的元帥結構的方法是像這樣:編組數組結構與類

[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; 
} 

注意如果附屬數據是一個結構這工作得很好:

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(); 
    } 
} 

現在這個工作一般細的問題,以下類型出現!但是如果SubData是一個類,它會導致Marshal.PtrToStructure引發一個FatalExecutionEngineError。我想堅持類,因爲有時我的類型有默認值,結構不能有字段初始值設定項和默認構造函數,而且其中一些類型也很大。

感謝您的幫助。

編輯:錯誤信息是「運行時遇到了一個致命錯誤,錯誤地址是0x6af99aec,在線程0x348上,錯誤代碼是0xc0000005,這個錯誤可能是CLR或者不安全或不可驗證的用戶代碼部分,這個錯誤的常見來源包括COM-interop或PInvoke的用戶編組錯誤,這可能會破壞堆棧。「

+0

你會得到什麼錯誤? – SLaks 2012-03-27 04:19:40

+0

@SLaks:我只是將它添加到描述中。 – Asik 2012-03-27 05:49:35

回答

1

一個類是一個引用類型,因此當使用Marshal.PtrToStructure時,它將在Subdata的位置複製一個指針並且沒有值。
將Subdata聲明爲struct時,將複製子數據的實際值。
因此,在進行編組時,必須使用結構。您可能仍然有一個類,它將在構造函數中使用struct版本。
可以例如通過使用

的sizeof

地看到,大小會有所不同證明這一點。

+0

當你編組一個類時,它不會複製一個指針,而是複製類的內容。爲什麼對於類的數組和數組的結構不一樣呢?你當然是對的,但這對我來說沒有意義。 – Asik 2012-03-27 06:21:37

+0

您正在討論類中的類屬性。這顯然是一個指針。 – weismat 2012-03-27 06:28:52