【发布时间】:2016-10-12 10:12:44
【问题描述】:
我正在尝试为一些 fortran 代码创建一个 c++ 包装器(使用 MSVS2013)。应该从 DELPHI 调用包装器(在 DELPHI 5 中创建的旧代码 - 我无法触及)。 (DELPHI -> C++ dll -> fortran dll)
目的是一些数据structs (recordin delphi) 与int's 和double's 和double[]'s 从delphi 传递到fortran 进行计算。
c++ dll -> fortran 没问题 - 我已经用另一个 c++ 可执行文件进行了测试。有用。问题是当 delphi 调用 c++ 而 c++ 调用 fortran 时。然后我收到一个错误提示
项目“myDelphiProject.exe”引发异常类 EZeroDivide,并带有消息“浮点除以零”。
如果没有调用 fortran,调用 c++ 包装器没有问题。
我已经测试并确认所有变量都能在 delphi 和 c++ 之间通过。调用约定设置为cdecl。
简化代码: 德尔福
interface
rec1 = record
var1,var2: double;
end;
procedure myCppWrap(record1: myrecord); cdecl; external 'mycppwrap.dll' name '_myCppWrap'
implementation
procedure MyDelphiFunc();
var
...
begin
myCppWrap(rec1)
...
简化的 c++ 代码:
struct rec1
{
double var1,var2;
}
extern "C" __declspec(dllexport) __cdecl myCppWrap(rec1 r1);
extern "C" *myFortranSub(double *varF1,double *varF2);
简而言之: DELPHI -> C++ 有效,C++ -> Fortran 有效,DELPHI -> C++ -> Fortran 无效。
有人知道出了什么问题吗?
编辑: 好的..所以我设法缩小范围: 我除以零导致无穷大(这是给定输入的正确内部结果 - 这不是 fortran dll 的直接输出)。 当使用默认发布设置编译fortran dll时,这在由c ++调用但不是从delphi调用时效果很好。 但是,在 c++ 和 delphi 中使用调试设置时它确实有效。 我将变量输出到文本文件(除法之前和之后)以进行验证,在所有 4 种情况下,除数均为 0,并且在三种情况下结果为“inf”。在调试和发布模式下,我对浮点异常处理“产生 NaN、有符号无穷大和非正规结果”具有相同的设置。
事实证明,这更像是一个编译器设置/标志问题,而不是编码问题......
谁有这方面的经验?? (我正在研究一个小型且可验证的代码)
【问题讨论】:
-
问题是你的代码有缺陷。除非您实际显示minimal reproducible example,否则我们看不到您的代码。要么这样做,要么自己做一些调试。显示假代码根本没有帮助。您的 C++ 代码显然是假的。这些函数没有声明返回值。
-
okidoki.. 我在上面:)
-
这是因为 Delphi 运行时取消屏蔽浮点异常。如果您的代码旨在使用然后被屏蔽,则将它们屏蔽。