C++ 捕获.NET中的非托管dll异常

C++ 捕获.NET中的非托管dll异常,c++,.net,vb.net,winapi,dll,C++,.net,Vb.net,Winapi,Dll,我使用的是一个非托管DLL,其函数抛出std::exception 我使用的是.NET DLL包装器,因此它可以分发到.NET程序中使用 我希望能够捕获来自本机异常的消息,但我得到的只是System.Runtime.InteropServices.SEHException(“外部组件引发了异常”) 有没有办法传播异常详细信息?也许我应该从本机DLL导出自定义异常?我该怎么做 谢谢 本机DLL: __declspec(dllexport) void __stdcall W32DLLFunc(int

我使用的是一个非托管DLL,其函数抛出
std::exception

我使用的是.NET DLL包装器,因此它可以分发到.NET程序中使用

我希望能够捕获来自本机异常的消息,但我得到的只是
System.Runtime.InteropServices.SEHException(“外部组件引发了异常”)

有没有办法传播异常详细信息?也许我应该从本机DLL导出自定义异常?我该怎么做

谢谢

本机DLL:

__declspec(dllexport) void __stdcall W32DLLFunc(int param) {
  if (param < 0) {
    throw new exception("Error: param must be > 0");
  }
  ...
}
vb.net程序:

Try
  W32DLLFunc(-1)
Catch ex As Exception
  MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

本机C++异常是本机C++异常。他们不工作,不是C++的东西。它们甚至不在C++的不同版本之间工作。


本机C++异常对互操作性不好。 从DLL返回错误信息的标准机制是返回一个值以指示成功或失败,并在函数失败时使用和传递错误代码

如果您想要一个标准机制返回比错误代码更多的信息,那么您需要查看COM,它已经提供了

但仅仅定义一些错误代码就更简单了

如果可能的话,我会修改原始的DLL,这样它就不会泄漏任何异常。如果这是不可能的,因为现有的C++客户端依赖于当前的设计,那么我将添加一个并行API:每个导出函数的新版本,调用原始函数,捕获异常并返回错误代码。这是所有可以隐藏在宏中的样板文件。如果你不能接触DLL,我会添加一个本机包装来翻译异常

更新

根据的建议,另一个选项是创建混合模式部件

将.NET类添加到现有的C++库中。这应该为调用原始API、捕获任何异常、将详细信息复制到.Net异常并抛出.Net异常的每个API函数提供一个包装器


通过在DLL内保持所有本地异常处理,避免了跨越DLL边界的C++异常的问题。包装的异常可以在任何.Net语言中使用,而无需为导出的函数创建声明。唯一的缺点是您需要一个额外的API来与其他本机代码进行互操作。

没错,著名的
E msc
例外。我将删除我的评论,以换取投票权。您还可以添加一个关于编写C++/CLI包装器的注释,将C++异常转换为.NET异常,这似乎是最干净的解决方案。混合模式程序集甚至可以由本机代码和托管代码使用。我想到了一个C++/CLI包装器,但我不知道本机异常是如何与C++/CLR交互的。几乎意味着它会起作用,所以我尝试了一下,它确实起了作用。我已经更新了我的答案。
Try
  W32DLLFunc(-1)
Catch ex As Exception
  MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try