C # не перехватывает необработанные исключения из неуправляемых C ++ dll - PullRequest
16 голосов
/ 19 ноября 2010

У меня есть неуправляемая DLL C ++, которая вызывается из приложения C #, я пытаюсь заставить приложение C # перехватывать все исключения, чтобы в случае сбоя DLL из-за неуправляемого исключения пользователь получит наполовину приличное сообщение об ошибке (приложение C # представляет собой веб-сервис, реализующий собственный обработчик http).

У меня проблема в том, что не все типы ловятся. Поэтому, если я создаю следующее и запускаю приложение C #, тогда dll выдает ошибку, и все приложение завершается. Есть идеи?

Это создается в VS2005 и использует .Net framework v2

C ++ - Test.h

#ifndef INC_TEST_H
#define INC_TEST_H

extern "C" __declspec(dllexport) void ProcessBadCall();

#endif

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

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"Release\vc80.pdb "/ W4 / WX / nologo / c / Wp64 / Zi / TP / errorReport: приглашение

1 Ответ

5 голосов
/ 19 ноября 2010

Попробуйте перехватить, используя класс ExternalException:

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.externalexception%28v=VS.100%29.aspx

И попробуйте скомпилировать неуправляемую DLL-библиотеку C ++ с асинхронной обработкой исключений (/ EHa).Похоже, что вы получаете нарушение прав чтения в вашей DLL, которое является типом асинхронного исключения.

AFAIK, только .NET v4 и выше отключает доставку асинхронных исключений по умолчанию.Даже тогда вы можете добавить legacyCorruptedStateExceptionsPolicy = true в app.config, чтобы включить его.До этого он автоматически включался (убедитесь, что он установлен в false в app.config).

Обратите внимание, что я лично считаю, что AV в вашей неуправляемой DLL в любом случае по своей сути плохи (и опасны) иЭто, вероятно, правильное поведение для .NET - просто завершить приложение.Попробуйте вместо этого бросить std :: exception.Если вы настаиваете на перехвате асинхронных исключений, лучшим способом было бы иметь громоздкую DLL-библиотеку, которая оборачивает try-catch-all вокруг вызова потенциально ошибочных вызовов функций.Опять же, очень / не / рекомендуется (хотя я вижу, как это было бы полезно при отладке некорректно работающей DLL).

...