我们有一个用 C++ 在 Visual Studio 2012/13 中构建的 MFC 产品,它可以执行许多数学计算。我们通过协处理器使用浮点中断来帮助加速计算,方法是设置 try/catch 块。这些中断在 Windows 7 中运行良好,但 Windows 10 的更新之一打破了这一顺序。虽然“信号”调用仍为“处理程序”回调设置正确的指针,但 Windows 10 会忽略它。(相同的代码在控制台程序中工作;它只在 MFC 代码中失败,即使是最简单的剥离示例)。我们有一个使用 SEH 的解决方法,但我们仍然想知道为什么会发生这种情况。感谢您提供任何信息。
相关代码是,处理程序抛出 FloatException(请注意,中断永远不会到达 Windows 10 中的处理程序):
_clearfp();
_controlfp_s(0, _EM_INEXACT, _MCW_EM);
signal(SIGFPE, (fptr)HandleMathError);
try
{
...calculate
}
catch (FloatException &e)
{
...recover
_fpreset();
_clearfp();
_controlfp_s(0, old_control_word, _MCW_EM);
signal(SIGFPE, SIG_DFL);
return;
}
为了完整起见,为了查看 MFC 故障,所需的代码至少有 9 个文件左右。首先生成一个简单的 MFC 应用程序,使用:单文档、文档/视图、mfc 标准接口、静态库、无复合文档、无数据库、经典菜单。然后,在 MainFrm::OnCreate 中,插入上面的中断代码,其中“raise(SIGFPE)”作为唯一的计算。为“HandleMathError”和“Float Exception”添加一个定义:
typedef void( *fptr )( int );
void __cdecl HandleMathError( int sig, int subcode );
class FloatException : public std::exception
{
public:
FloatException( int _foo )
{
foo = _foo;
}
int foo;
};
void __cdecl HandleMathError( int sig, int subcode )
{
throw FloatException( subcode );
return;
}
使用此代码,在 Windows 7 中输入中断处理程序,而在 Windows 10 中不输入。使用信号对存在的处理程序的测试在两个操作系统上都是肯定的;Windows 10 忽略处理程序。