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

Vir*_*721 4 c++ windows exception try-catch

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

我这样扔:

throw "ClassName::methodName() - Error message";
Run Code Online (Sandbox Code Playgroud)

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

try {
    while(GetMessage(args...)) {
        TranslateMessage(args...);
        DispatchMessage(args...);
    }
}
catch( const char * sExc ) {
    ::MessageBox(args...);
}
Run Code Online (Sandbox Code Playgroud)

我首先认为这是类型不匹配的问题,但后来我添加了带有省略号的 catch(...) ,但我仍然什么也没捕获。如果你问,是的,我确信抛出了异常。这不是与某种异步性或类似问题相关的问题吗?

感谢您的帮助 !

Han*_*ant 5

这取决于发送的具体消息。但不是,并非所有这些都允许通过 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 并检查您的程序是否在其中列出。只需删除该条目即可。

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