在Delphi 2010和Delphi 2007中,我在WebBrowserBeforeNavigate / WebBrowserDocumentComplete上使用Set8087CW来防止ActiveX内的FPU错误导致我的应用程序瘫痪。
但不知何故,这在Delphi XE2中不起作用,至少在64位模式下是这样。
当点击链接(任何)时,我得到“浮动除以零”。 (将网站地址或内容初始加载到TWebBrowser中工作正常。)
callstack显示这发生在system32 \ D3D10Warp.dll(可能由IE9使用?)中,以响应TApplication.ProcessMessage(以及一些???介于两者之间)
答案 0 :(得分:10)
您需要屏蔽64位的SSE异常,因为64位代码通常使用SSE来执行浮点运算。
调用SetMXCSR
以更改SSE单元的控制状态。就个人而言,我会继续掩盖8087例外,因为64位代码完全可以自由地使用8087单元,如果它愿意的话。调用Web浏览器代码时要使用的神奇MXCSR值为$1F80
。这是MXCSR的默认Windows值。
或者,您可以致电SetSSEExceptionMask
并SetFPUExceptionMask
通过exAllArithmeticExceptions
来屏蔽所有例外情况。这些便捷方法可以使您的代码更具可读性。
如果您对只需要在x86下的8087和x64下的SSE上屏蔽异常感到满意,那么您只需调用SetExceptionMask
即可。这将在x86下更改8087控制状态,并在x64下更改SSE控制状态。
如果我必须在设置整个控制状态或使用便捷方法来改变状态的异常屏蔽部分之间做出选择,我会设置整个控制状态。这些ActiveX控件是在您将使用MS工具并期望特定FP控件状态的假设下编写的。我会给这些控件提供他们期望的精确控制状态,然后在从控件返回执行时恢复到Delphi控件状态。