Это действительно проблема, но она настолько эзотерична, что я решил поделиться ею для других пользователей.
Возможно, другие могут предложить причины?
В любом случае, я работаю над "смешанным режимом".NET-приложения, написанным на управляемом С++, но с тяжелыми ссылками на существующие родные библиотеки.
Проблема заключалась в том, что необработанные управляемые исключения закончились как Нарушения доступа Win32. Я имею в виду, что вместо того, чтобы показывать хороший диалог .NET, вы получаете необработанное управляемое исключение, вместо этого я бы получил более старый стиль "Необработанное событие win32 exception произошло в...".
Вот интересная вещь: если я запустил приложение в отладчике, то заброшенное управляемое исключение попадет правильно. то есть отладчик показывает мне строку.
Однако при нормальной работе он превратится в это нарушение доступа. Прикрепление отладчика в этот момент создавало бы небольшую полезную информацию (это даже не показало бы разумной трассировки стека).
Итак, для меня это говорит о том, что что-то происходит в собственном коде незадолго до того, как необработанное управляемое исключение попадает в обработчик исключений.
Так или иначе, мне удалось решить проблему, сравнив мой проект с чистым новым проектом на С++, сгенерированным Visual Studio 2008.
Исправление должно состоять в следующем:
-
Измените флаг /SUBSYSTEM (свойства проекта → Linker- > System- > SubSystem) от/SUBSYSTEM: WINDOWS до "Не задано"
-
Переключение с использованием старого стиля WinMain() на использование нового стиля main().
то есть. это было
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
И теперь
int main(array<System::String ^> ^args)
[Почему я использую этот странный _tWinMain? Это то, что было создано Visual Studio.NET IDE много лет назад, когда вы создаете образец приложения с смешанным режимом Windows. Он всегда работал нормально (до сих пор), поэтому я никогда не беспокоился об этом. _tWinMain - это просто макрос для WinMain]
Я сделал это изменение, и проблема исчезла. Необработанные исключения .NET теперь получают правильную ловушку, поэтому я могу теперь их отлаживать.
Я также сделал обратное изменение для чистого примера С++-приложения и доказал, что это причина.
Итак, на самом деле мои вопросы: что происходит?
Было ли это просто, что я использовал старый стиль WinMain вместо нового "main (array ^)"?
Должен ли я сообщить об этом Microsoft (кому-нибудь это понравится;-))?