为Boost Logger定义工厂时wchar_t与char适配相关编译错误求解
解决方案
你的编译错误本质是字符类型不匹配:Windows下Boost.Log的文件sink默认使用wchar_t作为文件名的字符类型,而默认的parse_formatter生成的是char类型的格式化器,两者输出流字符类型不兼容。以下是两个Boost 1.70版本支持的可行方案:
方案1:全链路统一使用宽字符格式化器
把文件名相关的处理全链路切换为wchar_t类型,避免类型不匹配:
#include <boost/locale.hpp> // 也可使用Windows API MultiByteToWideChar实现编码转换,无需引入boost.locale // ... if (boost::optional< std::string > param = settings["FileName"]) { // 将配置中读取的UTF-8格式文件名模板转成宽字符 std::wstring w_pattern = boost::locale::conv::utf_to_utf<wchar_t>(*param); // 显式调用宽字符版本的格式化器解析接口 auto w_fmt = logging::parse_formatter<wchar_t>(w_pattern); auto composer = sinks::file::as_file_name_composer(w_fmt); // 注意此处backend必须为basic_text_multifile_backend<wchar_t>类型 backend->set_file_name_composer(composer); }
注意:之前修改sink_factory失败的原因是没有将后端、格式化器、工厂的字符类型全量统一为wchar_t,只要保持全链路字符类型一致即可编译通过。
方案2:封装编码转换适配层(侵入性更低)
如果不想修改现有日志系统的字符配置,可以自定义文件名生成器,将char格式化器的输出转成Windows支持的宽字符文件名:
#include <boost/log/sinks/file.hpp> #include <boost/locale.hpp> // 自定义文件名生成逻辑 auto filename_composer = [fmt = logging::parse_formatter(*settings["FileName"])] (const logging::record_view& record, sinks::file::file_name::type& output_name) { // 先将格式化结果输出到UTF-8字符串 std::string utf8_name; logging::formatting_ostream os(utf8_name); fmt(record, os); // 转成宽字符作为最终文件名 output_name = boost::locale::conv::utf_to_utf<wchar_t>(utf8_name); }; // 直接设置自定义生成器即可 backend->set_file_name_composer(filename_composer);
该方案不需要修改现有日志的其他配置,仅调整文件名生成逻辑,对原有代码侵入更小。
内容的提问来源于stack exchange,提问作者Joel
相关产品推荐
相关产品推荐

