2015-11-02 89 views
0

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

我写了一个最小的例子来说明其中I绊倒:

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的构造函数创建一个以控制台结束的跟踪消息。主要将其输出重定向到日志文件,但不会将dll输出重定向到相同的日志文件。我想dll包含自己的日志,我必须首先将其消息重定向到另一个核心。我搜索了这个问题,但我找不到一个简单的解决方案,尽管它在安装过程中认为这应该是主要的单线调用。并在dll界面中获取提升logcore单例的getter。

有没有我失踪的标准方式?我将如何重定向该日志记录?

编辑#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,文件系统,log_setup,日志,正则表达式,系统和线程(.count = 8)提供dll。

所以,即使结果正是我想要的方法是不同的,这与其他问题区分开来。 该DLL方法确保只有一个单独的核心dll。 我更喜欢拥有2个核心来提供dll,因此链接在一起对我来说是可以接受的。

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

回答

1

Boost.Log requires将被构建为共享库,如果您使用它从多个模块。库设计依赖于这一要求,并且日志核心不是库中唯一的单例。根据您使用的库功能,如果违反此前提条件,则可能会遇到难以调试问题的问题。与您当前使用的Boost.Log版本配合使用的代码也可能会与其他版本冲突。

+0

您参与开发Boost.Log,是否正确?我如何与你取得联系?我想分享一个关于如何做到这一点的愿景,看看你是否认为这是值得的。我希望通过作为程序员的贡献来帮助实现这些变化。 – Johannes

+0

当然。您可以在GitHub上提交pull请求和问题:https://github.com/boostorg/log/。有关该图书馆的讨论将在Boost开发人员邮件列表上进行讨论:http://www.boost.org/community/groups.html#main。 –

1

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

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

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

+0

@legalze感谢您的反馈 - 我能够做你所描述的,但我仍然想知道是否有另一种(内置)的方式。一个例子可能是创建一个sink/logger。一端连接到一个核心,另一端连接到另一个核心。由于我不知道设计,所以核心可能是一个具有可以连接的内部表示的外壳。这两种可能性都将允许静态链接和常用日志记录。我在问升压记录设计是否可以采用这些方法。 – Johannes

+0

该文档仅显示用于获取内核的单个静态获取器;除了通过这个全球性的单身人士之外,似乎没有什么办法可以分享它。所以,如果不修改源代码,您不会留下任何其他选项。 – legalize