【问题标题】:Floating point division by zero on showmodal Delphi XE8在showmodal Delphi XE8上浮点除以零
【发布时间】:2015-09-24 05:53:55
【问题描述】:

我最近将我的应用程序从 Delphi 2007 升级到了 Delphi XE8。在几种形式中,Form.showmodel 行抛出“浮点除以零”异常。在这些形式上根本没有进行算术运算。

我尝试在解决问题的 showmodal 之前执行以下代码。

  var
  CW, SW: word;

  function GetX87CW: word;
    ASM
    FStCW [Result]
  End;

  Function GetX87SW: word; // Assembler;
    ASM
    FStSW [Result]
  End;

  CW := GetX87CW; SW := GetX87SW;

  ShowMessage(Format('CW = $%4x, SW = $%4x',[CW,SW]));

我没有保存此代码并注释掉所有代码并再次重新编译也解决了问题的应用程序。

现在我关闭了 Delphi 并重新启动了 XE8 IDE。我打开项目,再次出现这个问题,但这一次,即使我写了上面的代码,它仍然抛出异常。

有没有人看到过这样的问题,有人可以说明导致这种问题的可能原因吗?

【问题讨论】:

  • 您没有提供足够的信息。你的表格在做什么?普通的 Delphi 应用程序永远不会出现这样的问题。
  • 这种形式的任何东西都不是非标准的、COM 甚至是 Windows API。它有几个用于数据库访问的 Tlistview 和 TADODataset。非常奇怪的部分是它适用于 Delphi 2007,但不适用于 Delphi XE8。
  • 没有minimal reproducible example就没有问题
  • @DivX ADO 是基于 COM 的。看我的回答。
  • 是的,我同意 ADO 是基于 COM 的,但 XE8 上的 TADODataset 是由 embarcadero 编写的,因此我希望它与 Delphi 2007 一样工作,因为使用 XE 8 编译的同一个项目会引发此异常。

标签: delphi floating-point delphi-xe8 divide-by-zero


【解决方案1】:

您是否使用 COM 对象,例如调用 .Net 程序集?还是 OpenGL?还是一些 OleDB/ADO 提供程序?任何其他外部.dll?我想是的。

听起来像this issue。您应该尝试通过为每次调用保存和恢复 FPU 异常标志来使外部非 Delphi 调用安全。

正如肯所写:

var
  Saved8087CW: Word;
begin
  Saved8087CW := Default8087CW;
  // If you want, disable all fpu exceptions 
  // with the next line.
  Set8087CW($133F);
  DoYourComOperationHere;
  Set8087CW(Saved8087CW);
end;

【讨论】:

  • 虽然要注意 Set8087CW 不是线程安全的,因此如果多个线程调用 Set8087CW,则不能使用此方法。
  • 接受这个答案,因为它解决了问题,但是我担心这个问题的影响可能非常高,因为我的所有项目都使用 ADO,并且此时更改 ADO 不是我的选择。这仅发生在几个表单上,因此我将进一步分析为什么它只发生在少数表单上,因为所有表单都使用 ADO。
猜你喜欢
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-13
  • 2018-03-03
  • 1970-01-01
相关资源
最近更新 更多