这似乎是 BCC32C 编译器中的错误。我猜它没有正确扩展以处理ExtendedDelphi 需要它。
如果您查看 CPU 窗口,则 BCC32 编译器会生成:
File5.cpp.14: SetVal(10.0L, 40.0L);
00401B8F 6802400000 push $00004002
00401B94 68000000A0 push $a0000000
00401B99 6A00 push $00
00401B9B 6804400000 push $00004004
00401BA0 68000000A0 push $a0000000
00401BA5 6A00 push $00
00401BA7 E80C000000 call Unit12::SetVal(long double,long double)
这是正确的。它首先推送10,然后40以Extended格式推送。请注意,每个Extended占用堆栈上的 12 个字节。
但现在看看 BCC32C 编译器的输出:
File5.cpp.14: SetVal(10.0L, 40.0L);
00401B5D 89E0 mov eax,esp
00401B5F D90554F14E00 fld dword ptr [$004ef154]
00401B65 DB38 fstp tbyte ptr [eax]
00401B67 D90558F14E00 fld dword ptr [$004ef158]
00401B6D DB780A fstp tbyte ptr [eax+$0a]
00401B70 E81F000000 call Unit12::SetVal(long double,long double)
00401B75 83EC18 sub esp,$18
它首先读取 32 个单精度浮点数40并将其存储为Extendedat [ESP]。到目前为止,一切都很好。但是随后它读取下一个 32 位单精度浮点数10(仍然可以),然后将其存储在[ESP+$0A],这显然是错误的(对于 Delphi)!它应该存储在[ESP+$0C]! 这就是为什么Pascal 函数在 处读取但由 BCC32C 在 处存储的第一个值是错误的。[ESP+$0C][ESP+$0A]
所以这似乎是一个错误。报告为https://quality.embarcadero.com/browse/RSP-15737
请注意,这是 BCC32C 推送和期望此类值的正常方式。在同一模块中的 C++ 函数中,即也用 BCC32C 编译,这很好用:
void __fastcall Bla(long double a, long double b)
{
printf("%Lf %Lf\n", a, b);
}
但是 Delphi 期望 10 字节Extended占用堆栈上的 12 字节,而不是像 BCC32C 那样的 10 字节。
奇怪的是,如果要调用的函数不是 Delphi__fastcall函数,而是普通的 C++ ( cdecl) 函数,BCC32C 编译器会将Extendeds ( long doubles) 分别存储在[ESP+$0C]和[ESP]中。
解决方法
正如 David Heffernan 评论的那样,您可以在记录中传递多个扩展。或者,您可以将它们作为var参数传递。在这两种情况下,它都不像调用那么简单SetVal(10.0, 40.0);。