使用扩展参数调用Delphi函数时发生C ++错误

角果

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

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

在同一个项目中,但在C ++单元中,我将此函数称为:

SetValue(10, 40);

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

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

在两种情况下,第二个参数均为40。

似乎Extended值和参数堆栈加载存在问题

我使用的是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标头,然后调用SetValue

这是全部了。

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

鲁迪·维特胡斯(Rudy Velthuis)

这似乎是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,然后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个单精度浮点数40并将其存储为Extendedat [ESP]到现在为止还挺好。但是随后它读取下一个32位单精度浮点数10(仍然可以),然后将其存储在中[ESP+$0A],这显然是错误的(对于Delphi)!它应该存储在[ESP+$0C]这就是为什么第一个是错误的,该值由Pascal函数在读取[ESP+$0C],但由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期望10Extended个字节在堆栈中占据12个字节,而不是BCC32C那样占用10个字节。

足够奇怪的是,如果要调用的函数不是Delphi__fastcall函数,而是普通的C ++(cdecl)函数,则BCC32C编译器会将Extendeds(long double分别存储[ESP+$0C]和中[ESP]

解决方法

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

调用python函数时发生错误,TypeError:returnbook()缺少1个必需的位置参数:“ self”

调用提升函数时发生未定义的错误

ecs错误:“调用...时发生错误(ClusterNotFoundException)”

当使用派生类型参数对Base和Derived进行模板化时,调用Base构造函数时发生编译器错误

尝试使用动态参数调用扩展方法时,为什么会出现CS1973错误

在使用React调用REST API时发生CORS错误

getTimestamp()-调用成员函数时发生致命错误

错误的参数的PostgreSQL调用函数

使用EvtSetChannelConfigProperty()函数时发生访问冲突错误

调用UDF时出现“此函数不带参数”错误

调用多个函数时发生递归错误

使用动态参数调用通用扩展方法时,C#编译器失败并产生误导性错误

在JavaScript中使用/定义函数时发生错误

当“错误:单元不带参数”时如何调用此Scala函数

使用laravel orm时发生错误“在null上调用成员函数count()”

错误:未捕获的类型错误:调用storage.set(对象项,可选函数回调)时发生错误Chrome扩展程序

扩展LockPatternActivity时发生错误

在C ++中使用ceil函数时发生计算错误

使用可变参数函数时C2780错误

使用“使用”或直接调用“ DIspose”时发生奇怪的“ Dispose”错误

定义参数时发生错误

发生没有匹配的函数来调用C ++中的错误

在列表中使用Lambda函数时发生Python:Syntax错误

在C中调用函数指针时发生编译错误

试图从R调用C ++函数时发生致命错误

Oracle PL / SQL:传递参数时发生函数错误

使用param调用函数时出现错误

当我尝试在 C++ 中调用继承的函数时发生错误

使用模板文字中的参数调用函数时出现 JS 错误