我正在尝试将Boost.Log集成到一个相当大的应用程序中,该应用程序由一个从 DLL 动态加载插件的主应用程序组成。最初的想法是将日志源传递给插件,以便它们可以添加日志消息。但是,一旦来自 DLL 的代码尝试将消息记录到提供的源,应用程序就会因访问冲突而崩溃。
方法一
以下最小示例说明了该问题:
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 编译)中因访问冲突而崩溃。
方法二
Boost.Log 提供了一种“全局存储”日志源的机制:
声明了全局记录器后,可以确保从应用程序代码的任何位置都可以线程安全地访问该记录器实例。该库还保证全局记录器实例即使跨模块边界也是唯一的。
听起来和我需要的完全一样。所以我设置了以下示例:
记录器.h
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>)
主文件
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 边界执行日志记录?