2015-03-18 1 views
1

У нас есть приложение, которое использует собственные библиотеки и написано на C++/CLI.Уточнение при обработке исключений в C++/CLI в смешанных сценариях с родным/управляемым

Наши собственные библиотеки имеют собственный класс исключений C++, ErrorException.

Код структурирован таким образом, что основной цикл приложения находится в собственном коде, который затем вызывает в (управляемый) код приложения, который затем, в свою очередь, иногда обращается в родную библиотеку.

Собственные библиотеки скомпилированы с помощью/EHsc (за исключением того, который скомпилирован с/EHa, что кажется мне неправильным, из-за проблемы, в которой catch (...) ловит структурированные исключения, такие как нарушения доступа!).

Что я сделал то, что я обернут (большинство) функции в коде ++/C CLI, который (я верю) может бросить управляемые исключения в MANAGED_TRY_START/MANAGED_TRY_END макросов, как определено ниже:

#define MANAGED_TRY_START try { 
#define MANAGED_TRY_END \ 
    } \ 
    catch(System::Runtime::InteropServices::SEHException^) { \ 
     throw; \ 
    } \ 
    catch(System::Exception^ ex) { \ 
     ConvertAndThrowSystemException(ex); \ 
     throw NULL; \ 
    } \ 

с ConvertAndThrowSystemException является функцией, которая превращает System :: Exception в исключение ErrorException и выдает это.

Теперь, мой вопрос, достаточно ли этого? Я спрашиваю, потому что это конкретное приложение проявляет частую нестабильность и проблемы с памятью, и я боюсь, что исключения ошибочны.

В соответствующей заметке мы используем dr.memory как нашу замену Valgrind для Windows для собственного кода, но это, похоже, не нравится .Net. У кого-нибудь есть рекомендация по аналогичному инструменту? Мы пробовали Deleaker, и мы получаем довольно странные результаты от него, как будто он утверждает, что объекты, выделенные стеком, просачиваются.

В частности, скажем, стек выглядит следующим образом: Foo() [родной] бар() [управляемый] Foobar() [родной] ...

и Foo() бросает C++ исключение , Вызов foobar() для foo находится в блоке try с соответствующим блоком catch() для типа, вызванного foo(). foobar() был скомпилирован с/Ehsc.

В каком случае из следующих случаев foobar() поймает исключение, при этом все промежуточные объекты стека C++ будут правильно уничтожены, если это произойдет?

  • бар() не имеет никаких попыток/поймать
  • бар() содержание 's обернута в моих MANAGED_TRY_START/MANAGED_TRY_END макросов

ответ

2

/EHa не является проблемой. Проблема catch (...).

/EHa - единственный способ, чтобы оба варианта были исключения ОС (исключения .NET включены в эту категорию) правильно раскручивают кадры стека C++ и имеют исключения C++, которые должным образом разматывают фреймы стека .NET.

+0

Большинство экземпляров 'catch (...)' в библиотеке, о которой я упоминал, предназначены для предотвращения исключений C++ из пересечения границ dll/language, и для этой цели не так много замены AFAIK – Bwmat

Смежные вопросы