发生的情况是.NetPaint()
在需要绘制窗口时调用。
显然.Net使这非常安全,并增加了额外的预防措施和错误处理。
现在我的Paint()
事件称为C++/CLI包装器 dll,它称为本机C++ dll。本机C++异常引发了访问冲突异常。
现在.Net捕获了该异常,并将其包装为托管SEHException
对象,并且我已经丢失了实际错误点的所有调用堆栈。
解决方案:
我们需要在.Net异常处理之前捕获异常。
通常的异常处理流程可以在网上找到,但是这个站点给出了实际流程的一个很好的例子:异常处理程序
.Net 似乎在调用SetUnhandledExceptionFilter处理程序之前捕获了异常并将它们包装起来。
因此,我添加了第一次机会异常处理程序,AddVectoredExceptionHandler
并通过检查错误代码来检查致命异常。
//SEH exceptions have code 0xC0000xxxx
#define SEH_TYPE (DWORD)0xC0000000L
//mask the last byte
#define SEH_MASK (DWORD)0xFF000000L
LONG WINAPI CheckForSEHException( struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter)
{
if ((lpTopLevelExceptionFilter->ExceptionRecord->ExceptionCode & SEH_MASK) == SEH_TYPE) //mask and check the last bits if it's an SEH exception
{
//handle exception here (create a dump or something)
return EXCEPTION_EXECUTE_HANDLER;
}
return EXCEPTION_CONTINUE_SEARCH;
}
异常代码可以在WinBase.h中找到,您可以按照实际错误代码的定义进行操作。(即寻找EXCEPTION_ACCESS_VIOLATION
)