gpt4 book ai didi

delphi - 使用扩展参数调用 Delphi 函数时出现 C++ 错误

转载 作者:行者123 更新时间:2023-12-02 10:11:58 26 4
gpt4 key购买 nike

在一个新的 Win32 项目中,我有以下 Delphi 函数:

procedure SetValue(value1, value2 : Extended);
begin
end;

在同一个项目中,但来自 C++ 单元,我调用此函数:

SetValue(10, 40);

当我使用 BCC32C (CLang) 编译时检查 value1 时,我得到 1.68132090507504896E-4932,这是不正确的。

用 BCC32(经典)编译,我得到 10。

在这两种情况下,第二个参数都是 40。

扩展值和参数堆栈加载似乎存在问题。

我使用 RAD Studio 10.1 Berlin。

我该如何解决这个问题?

更新

我没有包含声明,因为 hpp 是在编译时自动创建的。无论如何,声明是:

extern DELPHI_PACKAGE void __fastcall SetValue(System::Extended value1, System::Extended value2);

复制项目:

1-在Rad Studio中创建C++项目

2-使用上述SetValue函数添加一个Delphi单元

3-从 C++ 单元中,使用 #include 添加 hpp header 并调用 SetValue

这就是全部。

我需要使用扩展类型。我正在使用外部 Delphi 库,因此无法更改类型。上面的代码是问题的简化。实际上,问题是调用该库中在参数中使用 Extended 的函数。 Extended 是 Delphi 中的 native 类型,但在 C++ 中它被映射为 long double、10 个字节(对于 Win32)。

最佳答案

这似乎是 BCC32C 编译器中的错误。我猜它没有正确扩展来处理 Extended因为德尔福需要它。

如果您查看 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 ,然后40Extended格式。请注意,每个 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位单精度 float 40并将其存储为 Extended[ESP] 。到目前为止,一切都很好。但随后它读入下一个 32 位单精度 float 10 (仍然可以)但然后将其存储在 [ESP+$0A] ,这显然是错误的(对于 Delphi)!它应该存储在 [ESP+$0C] !这就是为什么要使用 Pascal 函数在 [ESP+$0C] 处读取的 first 值。 ,但由 BCC32C 存储在 [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 编译器将存储 Extended s ( long double s) 在 [ESP+$0C][ESP]分别。

解决方法

正如 David Heffernan 评论的那样,您可以在一条记录中传递多个扩展。或者,您可以将它们传递为 var参数。在这两种情况下,都不像调用SetVal(10.0, 40.0);那么简单。 .

关于delphi - 使用扩展参数调用 Delphi 函数时出现 C++ 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39231985/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com