Miq*_*uel 6 .net c++ vb.net dll winapi
我正在使用一个具有抛出函数的非托管DLL std::exception.
我正在使用.NET DLL包装器,因此可以将其分发以用于.NET程序.
我希望能够从本机异常中捕获消息,但我得到的只是 System.Runtime.InteropServices.SEHException("External component has thrown an exception.")
有没有办法传播异常细节?也许我应该从本机DLL导出自定义异常?我该怎么做?
谢谢
原生DLL:
__declspec(dllexport) void __stdcall W32DLLFunc(int param) {
if (param < 0) {
throw new exception("Error: param must be > 0");
}
...
}
Run Code Online (Sandbox Code Playgroud)
.net DLL:
[DllImport("nw32.dll", CharSet = CharSet::Auto)]
static void W32DLLFunc(int param);
Run Code Online (Sandbox Code Playgroud)
vb.net程序:
Try
W32DLLFunc(-1)
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Run Code Online (Sandbox Code Playgroud)
本机 C++ 异常是本机 C++ 异常。它们不能处理非 C++ 的东西。它们甚至不能在不同版本的 C++ 之间工作。
本机 C++ 异常不利于互操作性。
从 DLL 返回错误信息的标准机制是返回一个值来指示成功或失败,并在函数失败时使用SetLastError和GetLastError传达错误代码。
如果您希望标准机制返回比错误代码更多的信息,您需要查看 COM,它具有IErrorInfo.
但仅仅定义一些错误代码会更简单。
如果可能的话,我会更改原始的 DLL,这样它就不会泄漏异常。如果这是不可能的,因为现有的 C++ 客户端取决于当前的设计,那么我将添加一个并行 API:每个导出函数的新版本,调用原始函数、捕获异常并返回错误代码。这是可以隐藏在宏中的所有样板。如果您无法触及 DLL,我会添加一个本机包装器来转换异常。
更新
正如IInspectable所建议的,另一个选择是创建混合模式程序集。
将 .Net 类添加到现有的 C++ 库。这应该为每个调用原始 API 的 API 函数提供一个包装器,捕获任何异常,将详细信息复制到 .Net 异常中并引发 .Net 异常。
通过将所有本机异常处理保留在 DLL 内,可以避免 C++ 异常跨越 DLL 边界的问题。可以在任何 .Net 语言中使用包装的异常,而无需为导出的函数创建声明。唯一的缺点是您需要额外的 API 来与其他本机代码进行互操作。
| 归档时间: |
|
| 查看次数: |
2110 次 |
| 最近记录: |