Я пытаюсь интегрировать Boost.Log в довольно большом приложении, состоящем из основного приложения, которое динамически загружает плагины из DLL. Первоначальная идея заключалась в том, чтобы передать источник журнала для плагинов, чтобы они могли добавлять сообщения журнала. Однако, как только код из DLL пытается записать сообщение в предоставленный источник, приложение вылетает из-за нарушения прав доступа.
Подход 1
Следующий минимальный пример иллюстрирует проблему:
int main(int argc, char* argv[])
{
boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger;
// This is okay
BOOST_LOG_SEV(logger, boost::log::trivial::info) << "From main()";
// This crashes
logFromDll(logger);
return 0;
}
Где logFromDll
определен в отдельном (DLL) проекте:
Dll.cpp
TESTDLL_API void logFromDll(boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> &logger)
{
BOOST_LOG_SEV(logger, boost::log::trivial::info) << "From dll";
}
Как указано выше, это вылетает из-за нарушения прав доступа в logFromDll
(скомпилировано с помощью Visual Studio 2010).
Подход 2
Boost.Log предоставляет механизм для «глобальное хранилище» источников журналов:
Объявив глобальный регистратор, можно быть уверенным, что он имеет поточно-безопасный доступ к этому экземпляру регистратора из любого места кода приложения. Библиотека также гарантирует, что экземпляр глобального регистратора будет уникальным даже вне границ модуля.
Звучит в точности как то, что мне нужно. Итак, я создал следующий пример:
Logger.h
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>)
Main.cpp
int main(int argc, char* argv[])
{
boost::log::add_console_log
(
std::clog,
boost::log::keywords::format =
(
boost::log::expressions::stream << "[Custom format] " << boost::log::expressions::smessage
)
);
BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::info) << "From main()";
logFromDll();
return 0;
}
Dll.cpp
TESTDLL_API void logFromDll()
{
BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::info) << "From dll";
}
Это не приводит к сбою, но дает следующий результат:
[Custom format] From main()
[2014-06-19 10:22:28.435366] [0x00000233] [info] From dll
То есть настраиваемое форматирование, которое я установил в main.cpp, применяется только при входе в основной проект. Любые журналы из проекта DLL форматируются с использованием формата по умолчанию.
Итак, как я могу вести журнал через границы DLL, чтобы все параметры (форматирования), которые я установил в основном проекте, применялись правильно?