- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
(问题在最后)
我对不断更改 FPU 控制字的第三方 COM 组件感到非常头疼。
我的开发环境是Windows和Visual C++ 2008。正常的FPU控制字指定在各种情况下不应该抛出异常。我通过查看 float.h
中的 _CW_DEFAULT
宏以及在启动时查看调试器中的控制字来验证这一点。
每次我调用 COM 对象时,控制字都会在返回时被修改。这很容易防御。我简单地重置了控制字,一切都很好。问题是当 COM 组件开始调用我的事件接收器时。我可以在收到事件调用后立即通过重置控制字来保护我的代码,但是一旦我从事件调用返回,我就无法做任何事情。
我没有这个 COM 组件的源代码,但我正在与作者联系。我从他那里得到的回应是“嗯?”。我不认为他有丝毫线索我在说什么,所以我担心我必须自己做点什么。我相信他的运行时(我认为它是 Delphi 或 Borland C++,因为 DLL 充满了符号名称,全部以大写 T 开头),或者他正在使用的一些其他第三方代码,这导致了问题。我不认为他的代码明确修改了 FPU 控制字。
那么,我能做什么呢?从业务的角度来看,使用这个第三方组件势在必行。从技术角度来看,我可以放弃它,自己实现通信协议(protocol)。然而,这将非常昂贵,因为该协议(protocol)涉及处理信用卡交易。我们不想承担责任。
我迫切需要一个 hack-around,或者一些关于 Borland 产品中 FPU 设置的有用信息,我可以将这些信息传递给组件的作者。
有什么我可以做的吗?我不认为组件作者有能力修复它(从他相当无知的回答来看)。
我一直在考虑安装我自己的异常处理程序,我只是重置了处理程序中的控制字,并告诉 Windows 继续执行。我尝试使用 SetUnhandledExceptionFilter()
安装处理程序,但由于某种原因,未捕获异常。
感谢大家的建议。我已经向作者发送了说明,说明他可以做些什么来让不仅仅是我,还有他的代码的许多其他客户的生活更轻松。我建议他在 DllMain(DLL_PROCESS_ATTACH)
处采样 FPU 控制字,并保存控制字以备后用,这样他就可以在调用我的事件处理程序之前重置 FPU CW,并从我的事件返回电话。
目前,如果有人感兴趣,我有一个 hack-around。变通可能很糟糕,因为我不知道它会对他的 代码做什么。我早些时候收到确认,他没有在他的代码中使用任何 float ,所以这应该是安全的,除非他使用了一些依赖于 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% 的结论性答案,我很抱歉,但我无法将所有这些想法都写进评论中!
关于windows - 第三方代码正在修改 FPU 控制字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6933690/
我有一个加号/减号按钮,希望用户不能选择超过 20 个但不知道如何让它工作。我尝试使用 min="1"max="5 属性,但它们不起作用。这是我的代码和一个 fiddle 链接。https://jsf
我正在尝试复制顶部底部图,如示例 here但它没有正确渲染(紫色系列有 +ve 和 -ve 值,绿色为负值)留下杂乱的人工制品。我也在努力创建一个玩具示例来复制这个问题,所以我希望尽管我缺乏数据,但有
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 6 年前。 社区去年审查了是
这个问题在这里已经有了答案: Adding two positive integers gives negative answer.Why? (4 个答案) 关闭 5 年前。 我遇到了一个奇怪的问题
有谁知道如何将字符串值类型 -4,5 或 5,4 转换为 double -4.5 或 5.4? 最佳答案 只需使用 Double.parseDouble(Locale, String); 糟糕,我很困
我正在尝试根据 TextBlob 分类插入一个仅包含“正”或“负”字符串的新数据框列:对于我的 df 的第一行,结果是 ( pos , 0.75, 0.2499999999999997)我想要' 正
我对 VBA 非常陌生,无法理解如何在一个循环中完成 2 个任务。我非常感谢您的帮助。 我已经能够根据第 3 列中的数据更改第 2 列中的数值,但我不明白如何将负值的字体更改为红色。 表格的大小每月都
欢迎, 我正在使用 jquery 通过 POST 发送表单。 这就是我获得值(value)的方式。 var mytext = $("#textareaid").val(); var dataStrin
double d = 0; // random decimal value with it's integral part within the range of Int32 and always p
我有这个字符串: var a='abc123#xyz123'; 我想构建 2 个正则表达式替换函数: 1) 用 '*' 替换所有确实有 future '#'的字符(不包括'#') 所以结果应该是这样的
我正在使用 DialogFragment。当用户从 Gmail 平板电脑应用程序的屏幕与下面示例图片中的编辑文本进行交互时,我希望正面和负面按钮保持在键盘上方。 在我的尝试中不起作用,这是我的 Dia
从组装艺术一书中,我复制了这句话: In the two’s complement system, the H.O. bit of a number is a sign bit. If the H.O
是否有更好更优雅的方法来实现下面的简单代码(diffYear、A 和 B 是数字): diffYear = yearA - yearB; if (diffYear == 0) { A = B
我正在设计一种语言,并尝试确定 true 应该是 0x01 还是 0xFF。显然,所有非零值都将转换为 true,但我正在尝试确定确切的内部表示。 每种选择的优点和缺点是什么? 最佳答案 没关系,只要
在我的 dialogfragment 类的 OnCreateDialog 中,我正在这样做: AlertDialog.Builder builder = new AlertDialog.Builder
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda usin
我偶然发现了一个奇怪的 NSDecimalNumber 行为:对于某些值,调用 integerValue、longValue、longLongValue 等,返回意想不到的值(value)。示例: l
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda using
我有这个正则表达式来测试用户输入是否有效: value.length === 0 || value === '-' || (!isNaN(parseFloat(value)) && /^-?\d+\.
我想用高斯混合模型拟合数据集,数据集包含大约 120k 个样本,每个样本有大约 130 个维度。当我使用 matlab 执行此操作时,我运行脚本(簇号为 1000): gm = fitgmdist(d
我是一名优秀的程序员,十分优秀!