我试图将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;
}
Run Code Online (Sandbox Code Playgroud)
在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";
}
Run Code Online (Sandbox Code Playgroud)
如上所述,这会在访问冲突中崩溃logFromDll
(使用visual studio 2010编译).
Boost.Log为日志源的"全局存储"提供了一种机制:
声明了全局记录器后,可以确保从应用程序代码的任何位置对此记录器实例进行线程安全访问.该库还保证全局记录器实例即使跨模块边界也是唯一的.
听起来和我需要的完全一样.所以我设置了以下示例:
Logger.h
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>)
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
Dll.cpp
TESTDLL_API void logFromDll()
{
BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::info) << "From dll";
}
Run Code Online (Sandbox Code Playgroud)
这不会崩溃,但会产生以下输出:
[Custom format] From main()
[2014-06-19 10:22:28.435366] [0x00000233] [info] From dll
Run Code Online (Sandbox Code Playgroud)
也就是说,我在main.cpp中设置的自定义格式仅在我从主项目登录时应用.来自DLL项目的任何日志记录都使用默认格式进行格式化.
那么,如何以一种我在主项目中设置的所有(格式化)选项正确应用的方式跨DLL边界执行日志记录?