С# не вылавливает необработанные исключения из неуправляемой 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).