在记录中使用变体部件时,结构大小不正确

时间:2013-09-13 14:00:01

标签: delphi delphi-xe4 delphi-xe5

我有一个DLL项目,它提供了一个带有Delphi“变体部分”的类型定义,如下所示:

type TValue = record 
case Kind : cardinal of 
valueShortCard : ( ValShortCard : byte ); 
valueLongReal : ( ValLongReal : double ); 
end; 

我希望这个结构的大小为12个字节(4B为基数加上8B为double,因为这是两个类型中较大的一个)。

但是,如果我有一个应用程序并为DLL中的结构调用函数sizeof(),它表示大小为16个字节。

此外,如果我直接在.exe应用程序项目中声明相同的结构,sizeof()将返回12字节的正确大小。

如果我运行应用程序并尝试从编译的DLL中获取ValLongReal值,则返回的值不正确,并且它似乎在内存中移位了4个字节。

即。如果DLL中的“double”变量显示“40 45 9a e1 47 ae 14 7b”的值(以字节值解释),则应用程序从DLL读取后返回的值为“47 ae 14 7b 77 07 06 7d“。这意味着正确数据有4字节重叠,后4个字节不正确,从内存中的后续空间读取。

注意:在Delphi XE4中已经观察到这种行为,我们刚刚升级到XE5,但它的行为方式相同。 使用的操作系统是Win7 32位。

感谢您的建议

1 个答案:

答案 0 :(得分:3)

将其定义为:

type TValue = packed record 
  case Kind : cardinal of 
  valueShortCard : ( ValShortCard : byte ); 
  valueLongReal : ( ValLongReal : double ); 
  end; 

此处,sizeof(TValue)=12,正如您所料。

添加packed record强制不生成对齐。如果没有对齐,double将在8个字节边界上对齐,因此Kind将使用8个字节而不是4个字节,因此valueLongReal也会使用sizeof(TValue)=8+8=16情况下。

请注意,在Win64下,您需要来对齐double个变量。出于性能原因,这总是一个好主意。

另请注意,变量记录对齐方式与之前版本的Delphi XE3 AFAIR相同。