C++ / WIndows - 无法捕获异常

C++ / WIndows - Can't catch exceptions

本文关键字:捕获异常 WIndows C++      更新时间:2023-10-16

我是Windows api的初学者,所以这里一定有什么我不明白的地方。在我的主函数中,我使用 try-catch 来捕获所有未捕获的异常,但由于某种原因,我从代码中的其他地方抛出的异常永远不会被捕获。我的应用程序使用单个(主)线程。

我像这样扔:

throw "ClassName::methodName() - Error message";

并捕获消息循环之外的异常:

try {
    while(GetMessage(args...)) {
        TranslateMessage(args...);
        DispatchMessage(args...);
    }
}
catch( const char * sExc ) {
    ::MessageBox(args...);
}

最初认为这是类型不匹配的问题,但后来我添加了一个带有省略号的 catch(...),但我仍然什么也没找到。如果你问,是的,我敢肯定会抛出异常。这不是与某种异步性或类似的东西有关的问题吗?

感谢您的帮助!

这取决于要调度的特定消息。 但是不,并非所有人都允许通过Windows内部代码展开堆栈。 特别是涉及窗口管理器的消息,例如WM_CREATE。 Windows 内部有一个支持器,可以防止堆栈通过该关键代码展开。 在 64 位版本的 Windows 7 上运行的 32 位代码中也存在异常问题,当消息需要多次遍历 Wow64 边界时,它们可能会被吞噬。 在 Windows 8 中修复。

在更高版本的Windows上,这还可以激活"自我修复"代码,自动激活吞噬异常的appcompat填充程序。 您会收到通知,很容易关闭。 然后,你将在"VS 输出"窗口中看到首次机会异常通知,但程序将继续运行。 对用户来说也许还可以,但在调试时当然不是很好。 运行 Regedit.exe 并导航到 HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Persisted,然后检查您的程序是否列在那里。 只需删除该条目即可。

长话短说,在消息循环之外捕获异常是不安全的。 您必须在窗口过程中执行此操作。

您正在谈论"Windows结构化异常处理"(http://msdn.microsoft.com/en-us/library/windows/desktop/ms680657%28v=vs.85%29.aspx)。不会引发C++异常。

如果你想走麻烦的路线:_set_se_translator

另请参阅:C 程序可以处理C++异常吗?(Windows API 未C++)