我们有一个.NET程序,可以调用非托管C ++中的主要功能。我在.NET端有一个全局异常捕获程序来捕获任何未处理的错误,但是非托管C ++ DLL中的访问冲突等错误可以在不进行任何记录的情况下关闭程序。在DLL中添加“全局”异常捕获器的最佳方法是什么?我可以在DllMain中这样做吗?
答案 0 :(得分:1)
您可以使用/EHa
异常处理标志,这将导致您的C ++ catch (...)
也捕获结构化异常,即访问冲突。这样做的缺点是你无法看到异常是什么。
或者,您可以使用结构化异常处理程序__try { } __except(FILTER) { }
来处理结构化异常。这允许您输出捕获的异常类型。但是,在具有__try
的函数中可以执行的操作存在限制,例如没有C ++异常处理或具有析构函数的对象。
但是,您可以通过调用包含C ++异常处理和原始代码的函数来绕过__try
限制。
void main() {
__try {
Foo();
}
__except(EXCEPTION_EXECUTE_HANDLER) {
// Log some error regarding the structured exception
}
return 0;
}
void Foo() {
try {
SomeCPPObject bar(1,2);
DoSomeStuff();
}
catch (const std::exception&) {
// Log the C++ exception
}
}
但要小心,因为在引发结构化异常后通常不应继续执行,因为程序的状态可能会被完全破坏。最好只使用这种类型的异常处理在退出之前记录错误。
答案 1 :(得分:1)
CLR无法捕获由本机代码启动的线程中引发的任何硬件异常。唯一的方法是使用SetUnhandledExceptionFilter(),您注册的回调在Windows即将拆除进程之前由Windows调用。
在一个也有托管代码的程序中使用它会充满陷阱和陷阱。 CLR也使用它,它必须生成NullReferenceException和DivideByZeroException等异常。你必须非常小心,不要破坏它。做一些事情,比如调用GetThreadId()并且只过滤你知道的本机线程的异常非常重要。接下来你要做的就是使用MiniDumpWriteDump()生成一个minidump,以便你可以调试崩溃。