2015-11-02 24 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

相關問題