Delphi XE2,TWebBrowser,浮点数除以零
在 Delphi 2010 和 Delphi 2007 中,我在 WebBrowserBeforeNavigate / WebBrowserDocumentComplete 上使用 Set8087CW,以防止 ActiveX 内的 FPU 错误导致我的应用程序瘫痪。
但不知怎的,这在 Delphi XE2 中不起作用,至少在 64 位模式下是这样。
单击链接(任何)时,我得到“浮点数除以零”。 (将网站地址或内容初始加载到 TWebBrowser 中效果很好。)
调用堆栈显示这种情况发生在 system32\D3D10Warp.dll(可能由 IE9 使用?)内部,以响应 TApplication.ProcessMessage(以及两者之间的一些 ??? )
In Delphi 2010 and Delphi 2007 I am using Set8087CW on WebBrowserBeforeNavigate / WebBrowserDocumentComplete to prevent FPU errors inside ActiveX to cripple my application.
But somehow this is not working in Delphi XE2, at least when in 64bit mode.
When clicking links (any) I get "float divide by zero". (The initial loading of a website address or content into TWebBrowser works fine.)
The callstack shows this to happen inside system32\D3D10Warp.dll (maybe used by IE9?) in response to TApplication.ProcessMessage (and some ??? inbetween the two)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要在 64 位上屏蔽 SSE 异常,因为 64 位代码通常使用 SSE 来执行浮点运算。
调用
SetMXCSR
更改上交所单位。就我个人而言,我会继续屏蔽 8087 异常,因为 64 位代码完全可以自由地使用 8087 单元,如果它愿意的话。调用 Web 浏览器代码时要使用的神奇 MXCSR 值是$1F80
。这是 MXCSR 的默认 Windows 值。或者,您可以调用
SetSSEExceptionMask
和SetFPUExceptionMask
传递exAllArithmeticExceptions
屏蔽所有异常。这些方便的方法将使您的代码更具可读性。如果您满意只需要屏蔽 x86 下的 8087 和 x64 下的 SSE 上的异常,那么您只需调用
SetExceptionMask
。这将改变x86下的8087控制状态,并改变x64下的SSE控制状态。如果我必须在设置整个控件状态或使用便捷方法仅更改状态的异常屏蔽部分之间做出选择,我会设置整个控件状态。这些 ActiveX 控件是在您将使用 MS 工具并期望特定的 FP 控件状态的假设下编写的。我会给这些控件提供它们期望的精确控制状态,然后在执行从控件返回时恢复到 Delphi 控件状态。
You will need to mask SSE exceptions on 64 bit because 64 bit code typically uses SSE to perform floating point arithmetic.
Call
SetMXCSR
to change the control state of the SSE unit. Personally I would continue masking 8087 exceptions since 64 bit code is perfectly at liberty to use the 8087 unit should it so wish. The magic MXCSR value that you want to use when calling the web browser code is$1F80
. This is the default Windows value for MXCSR.Alternatively, you can call
SetSSEExceptionMask
andSetFPUExceptionMask
passingexAllArithmeticExceptions
to mask all exceptions. These convenience methods would make your code more readable.If you are satisfied that you only need to mask exceptions on 8087 under x86 and SSE under x64 then you can just call
SetExceptionMask
. This will change the 8087 control state under x86 and change the SSE control state under x64.If I had to choose between setting the entire control state or using the convenience methods to change just the exception masking part of the state, I would set the entire control state. These ActiveX controls are written under the assumption that you will be using MS tooling and expect a specific FP control state. I would give these controls the exact control state that they expect and then revert back to the Delphi control state when execution returns from the controls.