简介 - 又长又无聊的部分
(问题在最后)
我对不断更改 FPU 控制字的第三方 COM 组件感到非常头疼。
我的开发环境是Windows和Visual C++ 2008。正常的FPU控制字指定在各种情况下不应抛出异常。我已经通过查看验证了这一点_CW_DEFAULT
宏发现于float.h
,以及在启动时查看调试器中的控制字。
每次我调用 COM 对象时,控制字都会在返回时被修改。这很容易防御。我只是重置了控制字,一切都很好。问题是当 COM 组件开始调用我的事件接收器时。我可以通过在收到事件调用后立即重置控制字来保护我的代码,但从事件调用返回后我无法立即执行任何操作。
我没有这个 COM 组件的源代码,但我正在与作者联系。我从他那里得到的回应是“嗯?”。我认为他对我在说什么一无所知,所以我担心我必须自己做点什么。我相信他的运行时(我认为是 Delphi 或 Borland C++,因为 DLL 充满了符号名称,全部以大写 T 开头),或者他正在使用的其他第三方代码,导致了问题。我不认为他的代码显式修改了 FPU 控制字。
那么,我能做什么呢?从商业角度来看,使用这个第三方组件势在必行。从技术角度来看,我可以放弃它,自己实现通信协议。然而,这将非常昂贵,因为该协议涉及处理信用卡交易。我们不想承担责任。
我迫切需要一种破解方法,或者一些有关 Borland 产品中 FPU 设置的有用信息,我可以将这些信息传递给组件的作者。
问题
有没有什么I可以做?我认为组件作者没有能力修复它(从他相当无能的回答来看)。
我一直在考虑安装自己的异常处理程序,其中我只是重置处理程序中的控制字,并告诉 Windows 继续执行。我尝试安装处理程序SetUnhandledExceptionFilter()
,但由于某种原因,异常没有被捕获。
- 为什么我没有捕获异常?
- 如果我成功捕获 FPU 异常,重置 FPU 控制字,然后让执行继续,就像什么都没有发生一样 - 那么所有的赌注都结束了吗?
Update
我要感谢大家的建议。我已向作者发送了说明,说明他可以采取哪些措施来让我以及他的代码的许多其他客户的生活变得更轻松。我建议他应该对 FPU 控制字进行采样DllMain(DLL_PROCESS_ATTACH)
,并保存控制字供以后使用,以便他可以在调用我的事件处理程序并从我的调用返回之前重置 FPU CW。
现在,如果有人感兴趣的话,我有一个解决方案。这种黑客攻击可能是一件坏事,因为我不知道它会做什么his代码。我之前已经收到确认,他在代码中没有使用任何浮点数,所以这应该是安全的,除非他使用一些依赖于 FPU 异常的第三方代码。
我对我的应用程序进行的两项修改:
- 包裹我的消息泵
- 安装窗户挂钩(
WH_CALLWNDPROC
)捕获绕过消息泵的极端情况
在这两种情况下,我都会检查 FPU CW 是否已更改。如果有,我将其重置为_CW_DEFAULT
.