加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

窗口 – 第三方代码正在修改FPU控制字

发布时间:2020-12-15 04:27:25 所属栏目:大数据 来源:网络整理
导读:介绍 – 漫长而无聊的部分 (问题是结束) 通过第三方COM组件,我不断改变FPU控制字,变得严重头痛. 我的开发环境是Windows和Visual C 2008.正常的FPU控制字指定在各种条件下不应抛出异常.我已经验证了这两个,同时查看float.h中找到的_CW_DEFAULT宏,以及在启动时
介绍 – 漫长而无聊的部分

(问题是结束)

通过第三方COM组件,我不断改变FPU控制字,变得严重头痛.

我的开发环境是Windows和Visual C 2008.正常的FPU控制字指定在各种条件下不应抛出异常.我已经验证了这两个,同时查看float.h中找到的_CW_DEFAULT宏,以及在启动时查看调试器中的控制字.

每当我打电话到COM对象时,控制字在返回时被修改.这很容易防御.我只是重新设置控制字,一切都很好.问题是当COM组件开始调用我的事件接收器.我可以在收到活动通知后立即重新设置控制字来保护我的代码,但一旦从事件调用返回,我就不能做任何事情.

我没有这个COM组件的源代码,但我与作者联系.我从他那里得到的答复是“嗯?我不认为他有丝毫的线索我在说什么,所以我怕我必须自己做一些事情.我相信他的运行时间(我认为是Delphi或Borland C,因为DLL中充满了符号名称,全部以资本T开头)或者他正在使用的其他第三方代码,这是导致问题的.我不认为他的代码显式修改了FPU控制字.

那我该怎么办?从商业角度来看,使用这个第三方组件是至关重要的.从技术的角度来看,我可以把它淹没,并且自己实现通信的协议.然而,这将是非常昂贵的,因为该协议涉及处理信用卡交易.我们不想承担责任.

我迫切需要一个黑客,或者有关Borland产品中FPU设置的一些有用的信息,我可以将其传递给组件的作者.

问题

有什么可以做的吗我不认为组件作者有什么需要解决它(通过从他相当无知的反应来判断).

我一直在想安装我自己的异常处理程序,其中我只是重新设置处理程序中的控制字,并告诉Windows继续执行.我尝试使用SetUnhandledExceptionFilter()安装处理程序,但由于某些原因,异常未被捕获.

为什么我不抓住例外?
>如果我成功抓住FPU异常,重新设置FPU控制字,只是让执行继续,因为没有发生任何事情 – 所有的赌注呢?

更新

我想感谢大家的建议.我已经发送了作者的指示,说明他可以做些什么,使生活不仅仅是我,而且他的代码的许多其他客户.我向他建议,他应该在DllMain(DLL_PROCESS_ATTACH)上采样FPU控制字,然后保存控制字以供以后使用,以便在调用我的事件处理程序并从我的电话返回之前,可以重置FPU CW.

现在,如果有人有兴趣,我有一个黑客.这个黑客可能是一个坏的,因为我不知道他的代码会做什么.我早些时候已经收到确认,他没有在他的代码中使用任何浮点数,所以这应该是安全的,除了他使用的一些第三方代码,它依赖于FPU异常.

我对我的应用程序做了两项修改:

包裹我的消息泵
>安装一个窗口挂钩(WH_CALLWNDPROC)来捕捉消息泵旁路的角落

在这两种情况下,我检查FPU CW是否已更改.如果有,我将其重置为_CW_DEFAULT.

解决方法

我认为您的这个组件是用Embarcadero产品编写的诊断很有可能是真实的. Delphi的运行库确实启用了浮点异常,对于C Builder来说也是如此.

关于Embarcaderos工具的好处之一是浮点错误被转换成语言异常,这使得数字编码变得容易多了.这对你来说不是很安慰!

整个地区是庞大的PITA.没有关于FP控制词的规则.这是一个完全免费的.

我不认为捕获未处理的异常不会完成工作,因为MS C运行时可能已经捕捉到这些异常,但我不是这方面的专家,可能是错误的.

我相信您唯一现实的解决方案是将FPU设置为您希望在执行到达代码时所需要的内容,并在执行离开代码时将其还原.我不太了解COM事件接收器,以了解为什么他们提出了这样做的障碍.

我的产品包括一个在Delphi中实现的DLL,并且我遇到了相反的问题.大多数呼叫的客户端都有一个禁用异常的FPU控制字.我们采用的策略是记住8087CW的入门级,在执行代码之前将其设置为标准的Delphi CW,然后在退出点恢复.在进行回调之前,还要保留呼叫者的8087CW,我们也要小心处理回调.这是一个简单的DLL而不是一个COM对象,所以它可能有点简单.

如果您决定尝试让COM供应商修改代码,则需要调用Set8087CW()功能.

然而,由于游戏没有规则,我相信COM对象供应商将拒绝更改代码并将其放在你身上.

对不起,如果这不是一个100%的决定性答案,但我无法将所有这些想法纳入评论!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读