问题描述
我有一个从 C# 应用程序调用的非托管 C++ dll,我试图让 C# 应用程序捕获所有异常,以便在 dll 由于非托管异常而失败的情况下,用户将收到一条不太正常的错误消息(C# 应用程序是一个实现其自己的 http 处理程序的 Web 服务).
I've got an unmanaged C++ dll which is being called from a C# app, I'm trying to get the C# app to catch all exceptions so that in the event of the dll failing due to an unmanaged exception then the user will get a half-decent error message (the C# app is a web service implementing it's own http handler).
我遇到的问题是并非所有类型都被捕获.因此,如果我创建以下内容并执行 C# 应用程序,则 dll 会引发错误并且整个应用程序终止.有什么想法吗?
The problem I have is that not all types are being caught. So if I create the following and execute the C# app then the dll throws an error and the entire application terminates. Any ideas?
这是在 VS2005 中创建并使用 .Net framework v2
This is being created in VS2005 and using .Net framework v2
C++ - 测试.h
#ifndef INC_TEST_H
#define INC_TEST_H
extern "C" __declspec(dllexport) void ProcessBadCall();
#endif
C++ - 测试.cpp
C++ - Test.cpp
#include <iostream>
#include <vector>
using namespace std;
void ProcessBadCall()
{
vector<int> myValues;
int a = myValues[1];
cout << a << endl;
}
C# - Program.cs
C# - Program.cs
class Program
{
[DllImport("Test.dll", EntryPoint="ProcessBadCall")]
static extern void ProcessBadCall();
static void Main(string[] args)
{
try
{
ProcessBadCall();
}
catch (SEHException ex)
{
Console.WriteLine("SEH Exception: {0}", ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Exception: {0}", ex.Message);
}
}
}
正在使用以下编译器标志在发布配置下编译 dll.
The dll is being compiled under the release configuration with the following compiler flags.
/O2/GL/D "WIN32"/D "NDEBUG"/D"_CRT_SECURE_NO_WARNINGS"/D"_UNICODE"/D "UNICODE"/D "_WINDLL"/FD/EHa/MD/Fo"发布"/Fd"Releasevc80.pdb"/W4/WX/nologo/c/Wp64/Zi/TP/errorReport:prompt
推荐答案
尝试使用 ExternalException
类进行捕获:
Try catching using the ExternalException
class:
并且,尝试使用异步异常处理 (/EHa) 编译您的非托管 C++ DLL.看起来您的 DLL 中出现读取访问冲突,这是一种异步异常.
And, try compiling your unmanaged C++ DLL with asynchronous exception handling (/EHa).It looks like you're getting a Read Access Violation in your DLL which is a type of async exception.
AFAIK,默认情况下,只有 .NET v4 及更高版本禁用异步异常的传递.即便如此,您也可以将 legacyCorruptedStateExceptionsPolicy=true 添加到 app.config 以启用它.在此之前,它会自动启用(检查您是否已在 app.config 中将其设置为 false).
AFAIK, only .NET v4 and above disables the delivery of async exceptions by default. Even then, you could add legacyCorruptedStateExceptionsPolicy=true to the app.config to enable it. Prior to that, it's automatically enabled (check that you have got it set to false in app.config).
请注意,我个人认为非托管 DLL 中的 AV 本质上是坏的(而且危险),对于 .NET 来说,简单地终止应用程序可能是正确的行为.尝试抛出 std::exception 代替.如果您坚持捕获异步异常,最好的方法是拥有一个 thunking DLL,它将 try-catch-all 包裹在对潜在错误函数调用的调用中.再次强烈/不/推荐(尽管我可以看到它在调试行为异常的 DLL 时会有什么用处).
Note that it's my personal believe that AVs in your unmanaged DLL is inherently bad (and dangerous) anyway and it's probably the right behavior for .NET to simply terminate the app. Try throwing std::exception instead. If you insists on catching async exceptions, the best way would be to have a thunking DLL which wraps try-catch-all around the call to potentially buggy function calls. Again, highly /not/ recommended (although I can see how it would be useful in debugging the misbehaving DLL).
这篇关于C# 没有从非托管 C++ dll 中捕获未处理的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!