Информация об изменениях

Сообщение Про двойной перехват исключений в DLL (оформление кода) от 16.11.2020 13:49

Изменено 17.11.2020 4:07 acDev

Про двойной перехват исключений в DLL (как бы эстетичнее офо
Имеется чисто виндовая софтина, для которой можно писать плагины в виде DLL (_WIN32 и _WIN64).
Решил я переписать один из плагинов на плюсах ... с блэкджеком и исключениями. При этом эта софтина C++ исключений вообще не ожидает. Поэтому все исключения нужно перехватывать в каждой API функции и как то сообщать пользователю об ошибке (EventLog, MessageBox и т.п.).

Вот так код выглядел бы без учёта исключений:
class my::DLL { ... };

my::DLL g_dll;

int WINAPI DllFunc1(int arg1, int arg2)
{
    #pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
    return g_dll.func1(arg1, arg2);
}


А вот так примерно было бы с учётом ловли всех исключений:
class my::exception : public std::exception { ... };

class my::DLL { ... };

my::DLL g_dll;

int _DllFunc1(int arg1, int arg2)
{
    try {
        return g_dll.func1(arg1, arg2);
    }
    catch (my::exception & ex) {
        g_dll.init_exception(ex);
        throw;
    }
    catch (std::exception & ex) {
        g_dll.init_exception(ex);
        throw;
    }
    return -1;
}

int WINAPI DllFunc1(int arg1, int arg2)
{
    #pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
    __try {
        return _DllFunc1(arg1, arg2);
    }
    __except( g_dll.set_exception_info(GetExceptionInformation(), GetExceptionCode()) ) {
        g_dll.show_exception();
    }
    return -1;
}

Внутри set_exception_info планируется заюзать StackWalker.

Но вот как то не очень прикольно сколько дублирующего кода писать.
Неужели только макросы помогут?

DLL-ку переписываю на MSVC 2015.
exception dll cpp seh
Про двойной перехват исключений в DLL (оформление кода)
Имеется чисто виндовая софтина, для которой можно писать плагины в виде DLL (_WIN32 и _WIN64).
Решил я переписать один из плагинов на плюсах ... с блэкджеком и исключениями. При этом эта софтина C++ исключений вообще не ожидает. Поэтому все исключения нужно перехватывать в каждой API функции и как то сообщать пользователю об ошибке (EventLog, MessageBox и т.п.).

Вот так код выглядел бы без учёта исключений:
class my::DLL { ... };

my::DLL g_dll;

int WINAPI DllFunc1(int arg1, int arg2)
{
    #pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
    return g_dll.func1(arg1, arg2);
}

В этом варианте код простой и наглядный. Можно смело дублировать для 20 экспортных функций.

А вот так примерно было бы с учётом ловли всех исключений:
class my::exception : public std::exception { ... };

class my::DLL { ... };

my::DLL g_dll;

int _DllFunc1(int arg1, int arg2)
{
    try {
        return g_dll.func1(arg1, arg2);
    }
    catch (my::exception & ex) {
        g_dll.init_exception(ex);
        throw;
    }
    catch (std::exception & ex) {
        g_dll.init_exception(ex);
        throw;
    }
    return -1;
}

int WINAPI DllFunc1(int arg1, int arg2)
{
    #pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
    __try {
        return _DllFunc1(arg1, arg2);
    }
    __except( g_dll.set_exception_info(GetExceptionInformation(), GetExceptionCode()) ) {
        g_dll.show_exception();
    }
    return -1;
}

В этом варианте на каждую экспортную функцию нужно создавать ещё одну дополнительную функцию, т.к. нельзя в одной функции обрабатывать два разных типа исключений.
И уж как то совсем напряжно становится от мысли о дублировании 20 раз этого кода.

Примечание: Внутри set_exception_info планируется заюзать StackWalker (поэтому то и юзается __except).

Но вот как то не очень прикольно сколько дублирующего кода писать.
Неужели только макросы помогут?

DLL-ку переписываю на MSVC 2015.
exception dll cpp seh