Здравствуйте, PM, Вы писали:
PM>Это какая-то древня библиотека с codeproject для печати stacktrace?
Она самая.
PM>Если я ничего не путаю, в ней вроде были утечки памяти.
Погуглил. Вроде было такое. Но очень давно.
PM>Может стоит глянуть на что-то поновее, типа boost::backtrace, которую даже двигают в стандарт.
Из пушки по маленькому воробушку не хочется совсем. Да и мне кажется, что в "мире винды" больше всего юзают именно StackWalker.
PM>Если я правильно понял, нельзя выпускать исключения за пределы экспортируемых из DLL функций, и хочется как-то обрабатывать их?
Верно
PM>Начиная C++11 есть лямбды, для передачи блока кода в другую функцию, так что можно написать функцию которая будет обрабатывать исключения:
Отличная идея!
Как раз лямбды начинаю осваивать. С ними код лаконичным стал.
| Вот что у меня получилось |
| class my::exception : public std::exception { ... };
class my::DLL { ... };
class my::ExceptInfo { ... };
my::DLL g_dll;
template<typename R, typename F>
auto catch_cpp_exceptions(my::ExceptInfo & einf, R eval, F && func)
{
try {
return func();
}
catch (my::exception & ex) {
einf.init(ex);
throw;
}
catch (std::exception & ex) {
einf.init(ex);
throw;
}
return eval;
}
template<typename R, typename F>
auto catch_exceptions(my::ExceptInfo & einf, R eval, F && func)
{
__try {
return catch_cpp_exceptions(einf, eval, std::forward<F>(func));
}
__except ( einf.init(GetExceptionInformation(), GetExceptionCode()) ) {
// nothing
}
return eval;
}
int WINAPI DllFunc1(int arg1, int arg2)
{
#pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
my::ExceptInfo einf(g_dll);
return catch_exceptions(einf, -1, [&]{ return g_dll.func1(arg1, arg2); });
// ~einf() -> einf.show()
}
int WINAPI DllFunc2(int arg1, const char * filename, INT64 * psize)
{
#pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
my::ExceptInfo einf(g_dll);
int rc = catch_exceptions(einf, -1, [&]{ return g_dll.func2(arg1, filename, psize); });
if (einf.is_active()) {
einf.show(L"filename = '%S'", filename); // Aux info for user
if (psize)
*psize = -1LL;
return -1;
}
return rc;
}
|
| |
И теперь даже нет необходимости в
/EHa. И с указанием
/EHsc работает нормально.