我有一个C ++ DLL,代码如下:
LogMessage( "Hello world" );
try {
throw new int;
} catch( int* e ) {
LogMessage( "Caught exception" );
delete e;
}
LogMessage( "Done" );
此DLL由某些第三方应用程序加载,并调用上面的代码。问题是只调用了第一个LogMessage
- 即使有一个异常处理程序,控制流也会被转移到未知。
我看到了这一点,无法决定是否要调查一些模糊不清的错误,或者只是消费者应用程序的邪恶力量。
消费者应用程序是否真的可以覆盖DLL中的C ++异常处理?
编辑:在考虑了答案中列出的所有要检查的内容之后问题得到了解决。在实际代码中,它不仅仅是 throw ,还有一个特殊的函数用于抛出在调试版本中调用MessageBoxW()Win32调用的异常。并且消费者应用程序在显示消息框(它是NT服务)时遇到了麻烦并且有效地挂断了。所以这不是以任何方式处理C ++异常的问题。
答案 0 :(得分:1)
代码没问题。我用这个函数执行它:
void LogMessage( char* s )
{
cout << s << endl;
}
得到了正确的输出:
Hello world
抓到异常
完成
LogMessage 功能可能存在问题吗?
我建议调查(通过调试器或添加调试打印),流程是否到达try块,以及它是否到达catch块。
不是问题,它仍然不清楚,通过抛出指针而不是值来实现什么。我建议不要使用catch-by-pointer,在C ++ - FAQ-lite中查看推理here。
答案 1 :(得分:1)
代码看起来对我很好,但是我很想再加上一些catch子句来看看它是否正在击中其中一个。即,我投入:
catch (const std::exception &ex) {
... log exception ...
}
catch (...) {
... log exception ..
}
我希望它能够点击指针捕获(即使这不是一个好主意,请参阅Igor Oks提供的链接)或std :: exception,以防它无法分配内存。也就是说,它应该击中三个catch子句中的一个,因此异常无法逃脱DLL。
我还会将抛出的对象更改为值类型(即使它是int)并相应地更新catch子句以查看是否以这种方式改变了行为。
答案 2 :(得分:1)
首先,请检查LogMessage
调用是否刷新输出(使用<< endl
)。
虽然很牵强,但新调用是否可能抛出异常(内存不足)?我认为这是没有新例外的一个原因(只是为了增加伊戈尔所说的)。
答案 3 :(得分:1)
代码看起来还不错。但是,在抛出结构化异常throw new int;
之前,您是否可以检查是否存在任何未处理的异常。
LogMessage( "Hello world" );
try {
//some unhandled exception here
throw new int;
} catch( int* e ) {
LogMessage( "Caught exception" );
delete e;
}
LogMessage( "Done" );
如果是这种情况,那么您可以使用SetUnhandledExceptionFilter函数检查相同内容。
如果DLL已经提供了未处理的异常过滤器,并且返回EXCEPTION_EXECUTE_HANDLER
,则不会调用异常处理程序。
您需要使用_set_se_translator
将win32异常转换为c ++结构化异常。
答案 4 :(得分:0)
赠品实际上是在EDIT中。 “MessageBoxW()...... NT服务......有效地挂断了。”这是一个公平的描述。消息框位于与登录用户无关的桌面上。因此,它仍然存在,等待永远不会发生的鼠标点击。