С# не вылавливает необработанные исключения из неуправляемой dll С++
У меня есть неуправляемая dll С++, которая вызывается из приложения С#, я пытаюсь заставить приложение С# уловить все исключения, чтобы в случае сбоя dll из-за неуправляемого исключения, тогда пользователь получит сообщение с недостойным сообщением (приложение С# - это веб-сервис, реализующий собственный HTTP-обработчик).
Проблема заключается в том, что не все типы пойманы. Поэтому, если я создам следующее и выполняю приложение С#, тогда dll выдает ошибку, и все приложение завершается. Любые идеи?
Это создается в VS2005 и использует .Net framework v2
С++ - Test.h
#ifndef INC_TEST_H
#define INC_TEST_H
extern "C" __declspec(dllexport) void ProcessBadCall();
#endif
С++ - Test.cpp
#include <iostream>
#include <vector>
using namespace std;
void ProcessBadCall()
{
vector<int> myValues;
int a = myValues[1];
cout << a << endl;
}
С# - 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 скомпилируется в конфигурации выпуска со следующими флагами компилятора.
/O2/GL/D "WIN32" /D "NDEBUG" /D "_CRT_SECURE_NO_WARNINGS" /D "_UNICODE" /D "UNICODE" /D "_WINDLL" /FD/EHa/MD/Fo "Release \" /Fd "Release\vc80.pdb" /W 4/WX/nologo /c/Wp 64/Zi/TP/errorReport: prompt
Ответы
Ответ 1
Попробуйте поймать с помощью класса ExternalException
:
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.externalexception%28v=VS.100%29.aspx
И попробуйте скомпилировать вашу неуправляемую С++ DLL с асинхронной обработкой исключений (/EHa).
Похоже, вы получаете сообщение о нарушении чтения в своей DLL, которое является типом исключения async.
AFAIK, только .NET v4 и выше отключает доставку исключений async по умолчанию. Даже тогда вы можете добавить legacyCorruptedStateExceptionsPolicy = true в app.config, чтобы включить его. До этого он автоматически включается (убедитесь, что в app.config установлено значение false).
Обратите внимание, что мое личное мнение о том, что AVs в вашей неуправляемой DLL по своей сути является плохим (и опасным), и, вероятно, правильное поведение .NET просто прекращает работу приложения. Попробуйте вместо этого использовать std:: exception. Если вы настаиваете на том, чтобы ловить асинхронные исключения, лучшим способом было бы иметь thunking DLL, который обертывает попытку try-catch вокруг вызова потенциально вызванных ошибками вызовов функций. Опять же, высоко/не рекомендуется (хотя я могу видеть, как это было бы полезно при отладке ошибочной DLL).