如何将一个boost日志核心公开并注册到另一个

时间:2015-11-02 10:25:43

标签: c++ logging boost boost-log boost-logging

dll和可执行文件都使用boost :: log。他们最终使用不同的单一日志核心。如何将dll核心暴露给可执行文件并将dll-core注册到exe-core,以便我可以将它们重定向到一个日志文件中。

我写了一个最小的例子来说明我偶然发现的地方:

LogUser.hpp

#pragma once

#ifdef DYNLIB_EXPORTS
#define DYNLIB_API __declspec(dllexport)
#else
#define DYNLIB_API __declspec(dllimport)
#endif

class DYNLIB_API LogUser
{
public:
    LogUser();
    ~LogUser() {}
};

LogUser.cpp

#include "LogUser.hpp"
#include <boost\log\trivial.hpp>
LogUser::LogUser()
{
    BOOST_LOG_TRIVIAL(trace) << "LogUser constructed";
}

Main.cpp的

#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>

#pragma comment (lib, "dynlib.lib")
#include <dynlib/LogUser.hpp>

void setupLogging();

int main()
{
    setupLogging();
    BOOST_LOG_TRIVIAL(trace) << "main enter";
    LogUser dynamicLogUser;
    BOOST_LOG_TRIVIAL(trace) << "main exit";
    return 0;
}

void setupLogging()
{
    using namespace boost::log;
    add_common_attributes();
    register_simple_formatter_factory< trivial::severity_level, char >("Severity");
    add_file_log
        (
        keywords::file_name = "file.log",
        keywords::format = "[%TimeStamp%] [%ThreadID%] [%Severity%]: %Message%"
        );
}

LogUser编译成LogUser.dll。 LogUser的构造函数创建一条最终在控制台上的跟踪消息。 Main将其输出重定向到日志文件,但不会将dll输出重定向到相同的日志文件。我想dll包含自己的logcore,我必须首先将其消息重定向到另一个核心。我搜索了问题,我找不到一个简单的解决方案,虽然感觉这应该是在安装过程中主要的一线调用。并且在dll界面中使用boost logcore单例获取。

我缺少一种标准方式吗?我如何在此处重定向该日志记录?

编辑#1: - 在我的系统上输出和我想要发生的事情的虚构。 enter image description here

编辑#2: - 我提出了一个可能的解决方案here。 - 如果该提示解决了问题,我将删除此问题,因为它是一个克隆。

编辑#3: 我从EDIT#2实施了建议的解决方案。它有效,但不是我想要的。

基本上你应该#define BOOST_LOG_DYN_LINK。不幸的是,由于日志正在使用递归地也必须添加的其他库,因此不起作用。我最终得到了#define BOOST_ALL_DYN_LINK。 所有的提升现在都是动态的,V1.59可能是30个dll。在我的最小例子中,我必须为chrono,date_time,filesystem,log_setup,log,regex,system和thread(.count = 8)提供dll。

所以,即使结果正是我想要达到它的方式不同,这也将这个问题与其他问题区分开来。 DLL方法确保只有核心的一个dll单例。 我更喜欢有2个内核而不是必须提供dll,所以将两个链接在一起对我来说是可以接受的。

有没有办法在静态链接时获得相同的结果?

2 个答案:

答案 0 :(得分:1)

这一切归结为全局变量。 “Singleton”只是全局变量的另一个名称。

如果您将可执行文件和DLL静态链接到Boost,那么它们每个都有自己的单例(全局变量)。如果要共享它们,则必须将可执行文件和DLL链接到共享日志库,以便它们共享相同的全局单例。

这只是使用共享库的结果:由于全局数据,它们倾向于强制其他库也被共享。

答案 1 :(得分:1)

如果您从多个模块中使用它,那么

Boost.Log requires将构建为共享库。库设计依赖于该要求,并且日志核心不是库中唯一的单例。根据您使用的库功能,如果违反此前提条件,您或多或少会遇到难以调试的问题。与您当前使用的Boost.Log版本一起使用的代码也可能会破坏不同的版本。