Исключение C# DLL не перехватывается в неуправляемом C++

В рамках этого упражнения по ознакомлению с использованием C# DLL в неуправляемом C++ через COM я пытаюсь понять, как работает обработка исключений. Я написал крошечную dll C#, которая просто содержит функцию, которая генерирует исключение, и функцию C++, которая вызывает эту функцию и пытается перехватить исключение.

Вот DLL, написанная на C# с использованием Visual Studio 2012:

namespace ExceptionThrowingLib
{
    public interface IExceptionThrower
    {
        void ThrowException();
    }

    public class ExceptionThrower : IExceptionThrower
    {
        public ExceptionThrower() { }
        public void ThrowException()
        {
            using (StreamWriter writer = new StreamWriter("c:/misc/exceptionthrower.txt", true))
            {
                writer.WriteLine("Exception generation request received at " + DateTime.Now.ToString());
            }
            throw new Exception("This is a requested exception.");
            using (StreamWriter writer = new StreamWriter("c:/misc/exceptionthrower.txt", true))
            {
                writer.WriteLine("This should never appear in the output file.");
            }
        }
    }
}

А вот функция, которая пытается его использовать, написанная на C++ с использованием Visual Studio 2008:

void HandleException()
{   
    IExceptionThrowerPtr pThrower(__uuidof(ExceptionThrower));
    try
    {
        pThrower->ThrowException();
        AfxMessageBox(_T("No exception caught."));
    }
    catch (...)
    {
        AfxMessageBox(_T("I caught an exception!"));
    }
}

Когда я вызываю эту функцию, появляется сообщение "Исключение не обнаружено".

Я ожидал, что клиентская (C++) сторона сможет поймать объект _com_error и обработать его соответствующим образом, чтобы узнать, что произошло, но, похоже, ничего не перехватывается. Почему бы нет? Я делаю что-то неправильно?

Спасибо.

Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
0
77
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы на самом деле не делаете ничего плохого, но имеете неправильное понимание.

Код C++ не перехватывает исключение, потому что в код C++ не выдается исключение. Уровень CLR/interop в среде выполнения .NET перехватывает исключение до того, как оно будет передано обратно. Весь хороший код COM никогда не выдает исключение из метода или свойства COM, а возвращает код ошибки.

Каков код возврата (HRESULT) от ThrowException(). Это не должно быть S_OK, но может быть E_FAIL или какая-то другая описательная ошибка.

Уровень COM-взаимодействия прозрачно сопоставляет исключения .NET с HRESULTS, которые затем могут быть перехвачены собственными клиентами, как описано здесь. Код OP, по-видимому, использует реализацию автогенерируемая_com_ptr_t, которая в своей конфигурации по умолчанию выдает _com_error, если возвращаемый HRESULT указывает на ошибку.

Aurora 04.05.2019 16:38

Я нигде не читал, что он использует _com_ptr_t или какой-либо автоматически сгенерированный код. Он просто говорит о _com_error, который определен в comdef.h, если мне не изменяет память.

Joseph Willcoxson 06.05.2019 05:45

Я автоматически сгенерировал код интерфейса, установив для ComVisible значение true в AssemblyInfo.cs, выбрав «Регистрация для Com Interop» в настройках сборки проекта C# и используя #import для полученной библиотеки типов.

ROBERT RICHARDSON 06.05.2019 15:56
Ответ принят как подходящий

Вы использовали #импорт для создания реализации _com_ptr?

Если это так, позаботьтесь о том, чтобы опустить директиву raw_interfaces_only, так как она подавляет генерацию функций-оболочек для обработки ошибок.

Большое спасибо! Я создал классы C# и C++, слепо следуя директиве эта ссылка, которая не объясняла директиву raw_interfaces_only.

ROBERT RICHARDSON 06.05.2019 15:52

Другие вопросы по теме