具有预留空间的结构如何编组?

时间:2012-08-01 15:17:44

标签: vb.net .net-4.0 marshalling

问题:

我有一个固定大小的结构,我正在试图编组。此结构包含当前版本结构的许多有用字段以及最后保留用于将来修改的指定数量的未使用空间。

我应该如何设计这个结构,以便在修改结构时自动更新保留空间的大小?

虽然以下内容可以解决我的问题

'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))不是常量表达式。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

在进一步思考这个问题之后,我开始质疑我希望在结构的末尾暴露保留空间的有效性。实际上,没有任何东西可以引用保留部分。如果需要某些东西,那么正确的方法是修改结构本身以暴露保留空间的相关部分。

因此,结构应如下所示:

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

答案 1 :(得分: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