1

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

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

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

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

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

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

IE 如果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位。

谢谢你的建议

4

1 回答 1

4

将其定义为:

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在您的情况下也是如此。

请注意,在 AMD/Intel 下,出于性能原因,您应该更好地调整变量。double在 ARM 上,需要对齐。

另请注意,相对于以前的版本,Delphi XE3 AFAIR 更改了变量记录对齐方式。

于 2013-09-13T14:05:16.763 回答