5

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

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

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

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

4

1 回答 1

10

您需要在 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 控件状态。

于 2012-02-20T10:41:04.877 回答