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

时间:2013-09-13 13:00:44

标签: c++ windows exception try-catch

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

我这样扔:

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

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

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

我首先认为这是类型不匹配的问题,但后来我添加了一个带省略号的catch(...),但我仍然没有抓到任何东西。如果你问,是的,我确定会抛出异常。这不是一个与某种异步性有关的问题吗?

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

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

在以后的Windows版本中,这也可以激活“自我修复”代码,自动激活吞噬异常的appcompat填充程序。你会得到一个通知,容易解雇。然后,您将在VS Output窗口中看到第一次机会异常通知,但您的程序仍在运行。当然,当你正在调试时,对于用户来说可能并不是很好。运行Regedit.exe并导航到HKCU \ Software \ Microsoft \ Windows NT \ CurrentVersion \ AppCompatFlags \ Compatibility Assistant \ Persisted并检查您的程序是否列在那里。只需删除该条目即可。

长话短说,在消息循环之外捕获异常是不安全的。你必须在窗口过程中完成它。

答案 1 :(得分:1)

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

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

另请参阅:Can a C program handle C++ exceptions?(Windows API不是C ++)