【问题标题】:Delphi XE2, TWebBrowser, float divide by zeroDelphi XE2,TWebBrowser,浮点除以零
【发布时间】:2012-03-10 16:20:45
【问题描述】:

在 Delphi 2010 和 Delphi 2007 中,我在 WebBrowserBeforeNavigate / WebBrowserDocumentComplete 上使用 Set8087CW 以防止 ActiveX 中的 FPU 错误削弱我的应用程序。

但不知何故,这在 Delphi XE2 中不起作用,至少在 64 位模式下是这样。

单击链接(任何)时,我得到“浮点数除以零”。 (将网站地址或内容初始加载到 TWebBrowser 工作正常。)

调用堆栈显示这发生在 system32\D3D10Warp.dll(可能被 IE9 使用?)中以响应 TApplication.ProcessMessage(以及两者之间的一些???)

【问题讨论】:

  • 文档说 (docwiki.embarcadero.com/VCL/en/System.Set8087CW):Set8087CW 在 64 位 Windows 上:此控制字不控制浮点运算,因为 SSE 寄存器用于浮点在 64 位模式下,而不是 FPU(浮点单元)。但是 FPU 仍然存在于 64 位模式中,因此 SGet8087CW 设置控制字的值,就像在 32 位模式中一样。
  • @teran,是的,但是SGet8087CW 是什么?
  • @TLama Set8087CW 的拼写错误,复制自 docwiki.embarcadero.com/VCL/en/System.Set8087CW
  • @Tom 还有SetMXCSR。我的建议是同时使用它和Set8087CW。无论 Delphi 使用什么进行浮点运算,32 位和 64 位 Windows 都可以使用 FPU 和 SSE 操作。
  • @Tom,抱歉打错了。我的意思是 FPU(不是 FTP)。

标签: delphi 64-bit delphi-xe2 floating-point-exceptions


【解决方案1】:

您需要在 64 位上屏蔽 SSE 异常,因为 64 位代码通常使用 SSE 来执行浮点运算。

致电SetMXCSR 更改SSE 单元的控制状态。就我个人而言,我会继续屏蔽 8087 异常,因为 64 位代码完全可以随意使用 8087 单元,如果它愿意的话。调用 Web 浏览器代码时要使用的神奇 MXCSR 值是 $1F80。这是 MXCSR 的默认 Windows 值。

或者,您可以调用 SetSSEExceptionMaskSetFPUExceptionMask 传递 exAllArithmeticExceptions 以屏蔽所有异常。这些方便的方法将使您的代码更具可读性。

如果您对只需要在 x86 下的 8087 和 x64 下的 SSE 上屏蔽异常感到满意,那么您可以调用SetExceptionMask。这会改变x86下的8087控制状态,改变x64下的SSE控制状态。

如果我必须在设置整个控件状态或使用便捷方法更改状态的异常屏蔽部分之间做出选择,我会设置整个控件状态。这些 ActiveX 控件的编写假设您将使用 MS 工具并期望特定的 FP 控件状态。我会给这些控件提供它们所期望的确切控件状态,然后在从控件返回执行时恢复到 Delphi 控件状态。

【讨论】:

  • 感谢大家的帮助。我接受此响应作为解决方案,因为它深入解决了该主题(并且我直接使用 SetMXCSR 进行了测试,这似乎也有效。除了旧代码之外,我已更改我的代码以使用它。)
  • +1;谢谢,你介意我在博客上引用你的一些答案吗?
  • @JeroenWiertPluimers 我当然一点也不介意。请做我的客人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-13
  • 2018-03-03
相关资源
最近更新 更多