c# - 在 .NET 中读取 native win32 异常数据/参数

标签 c# c++ exception pinvoke seh

我正在尝试在托管 (.net/c#) 的 catch block 中接收有关我在 native (c++/win32) 中抛出的异常的数据。

例如,在c++中,我们可以:

void MyFunc()
{
    const char* data = "my exception info";
    ULONG_PTR args[1] { data };
    RaiseException(0,0,1,args);
}

此函数可以通过 C# 中的 P/Invoke 调用:

[DLLImport("MyLib.dll")]
extern public static void MyFunc();

static void Main()
{
    try { MyFunc(); }
    catch(SEHException seh)
    {
        // Where is my exception info? :(
    }
}

SEHException不包含来自导入的 DLL 函数的我的字符串。

SEHException.ErrorCode 总是显示为 E_FAIL,但在任何情况下我都想编码比 int 更丰富的数据。

我是不是遗漏了什么,或者是否有其他方法可以通过异常取回此字符串数据?

目的是通过设置 native 过滤器(如 SetUnhandledExceptionFilter,仅供引用),使用 native 堆栈跟踪重新引发 native 异常。

最佳答案

SEH 异常通常没有参数,而且数据方式也很少。实际上你所能得到的就是numeric exception codethe processor state when the exception happened (including the instruction pointer and stack pointer) .

C++ 异常处理使用的是用于启动处理程序的 SEH 异常,但 C++ 异常对象实际上存储在其他地方(详细信息在编译器及其运行时库内部)。从另一种语言访问它几乎是不可能的;甚至其他 C++ 编译器也有一段糟糕的时光。所有 C++ 异常共享一个异常代码。

手动调用 RaiseException,就像您正在做的那样,确实允许您存储异常参数,就像操作系统异常 EXCEPTION_ACCESS_VIOLATIONEXCEPTION_IN_PAGE_ERROR 一样,见EXCEPTION_RECORD on MSDN .使用 Microsoft C++ 编译器,您可以通过 GetExceptionInformation 访问它们。并且您肯定不应该将 C++ 对象(如 std::string)与 RaiseException 组合在一起——您错过了 C++ 编译器为这些对象的生命周期管理添加的额外魔法。不过,将字符串数据作为 const char* 传递给字符串文字应该没问题..

然后您将面临在 .NET 中检索此信息的问题。即使是这些有限的(异常代码、上下文和记录,没有 C++ 对象)信息,我认为您也无法从 .NET SEHException 对象中获得。您看到 E_FAIL 的原因是文档中这条注释的结果,而不是异常代码。

The SEHException class handles SEH errors that are thrown from unmanaged code, but that have not been mapped to another .NET Framework exception. The SEHException class also responds to the HRESULT E_FAIL, which has the value 0x80004005.

关于c# - 在 .NET 中读取 native win32 异常数据/参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25650561/

相关文章:

c# - HashSet 不删除对象

c# - 使用 xml 以外的应用程序数据结构

c# - 循环依赖

c# - 将 C# 委托(delegate)转换为单元测试

c++ - Reading BMP file C++(读取BMP文件头有问题)

c++ - Winsock2:select()函数给出 "invalid arguement error"(错误10022)?

c++ - 实现一个没有未定义行为的类似 std::vector 的容器

android-studio - Android studio : I am getting the following error "java.util.NoSuchElementException". 但是,我无法追踪错误

c# - 如何在特定异常时终止 .NET 应用程序 - 可能没有堆栈展开?

ruby - "rescue Exception"不拯救超时::net_http 中的错误