2012-08-01 47 views
1

問題:具有保留空間的結構如何編組?

我有一個固定大小的結構,我試圖編組。此結構包含當前版本的結構的許多有用字段以及末尾未使用空間的指定數量,這些空間留作未來修改使用。

我應該如何設計這個結構,以便在修改結構時保留空間的大小會自動更新?

而下面將解決我的問題

'Variable size structure 
<StructLayout(LayoutKind.Sequential, Pack:=1)> 
Structure UsefulData 
    Dim foo As SByte 
    Dim bar As Integer 
    Dim foobar As Short 
End Structure 

Const MAX_SIZE As Integer = 20 

'Fixed size structure 
<StructLayout(LayoutKind.Sequential, Pack:=1, Size:=MAX_SIZE> 
Structure Data 
    Dim current As UsefulData 
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=MAX_SIZE-System.Runtime.InteropServices.Marshal.SizeOf(GetType(UsefulData)))> 
    Dim reserved As SByte() 
End Structure 

但不編譯爲System.Runtime.InteropServices.Marshal.SizeOf(GetType(UsefulData))不是一個常量表達式。有任何想法嗎?

回答

1

經過對這個問題的進一步思考,我開始質疑我希望在結構的末尾公開保留空間的有效性。實際上什麼都不應該引用保留部分。如果有需要的話,那麼正確的做法是修改結構本身以暴露保留空間的相關部分。

因此結構應如下所示:

<StructLayout(LayoutKind.Sequential, Size:=20, Pack:=1)> 
Structure Data 
    Dim foo As SByte 
    Dim bar As Integer 
    Dim foobar As Short 
End Structure 
0

雖然我不認爲硬編碼數組的長度是理想的解決方案,但我將這個答案放在這裏以防沒有其他選擇。

Private const TOTAL_SIZE As Integer = 20 
Private const RESERVED_SIZE As Integer = 7 

<StructLayout(LayoutKind.Sequential, Pack:=1)> 
Structure Data 
    Dim foo As SByte 
    Dim bar As Integer 
    Dim foobar As Short 
    <MarshalAs(UnManagedType.ByValArray, SizeConst:=RESERVED_SIZE)> 
    Dim reserved As SByte() 
End Structure 

然後我可以添加任意一個單元測試或自定義生成行動,以確保System.Runtime.InteropServices.Marshal.Sizeof(GetType(Data)) = TOTAL_SIZE