結合boost.log跟Unreal Engine 4的log系統

最近在研究怎麼把boost跟UE4做結合使用,目前已經成功的將一些好用的boost library應用在專案上了,就先來整理一下相關該注意的技術事項吧。

首先我嘗試導入的是boost的log機制,雖然UE4本身已經有LOG系統了,但稍微survey了一下,看起來其實還是不太完整,而且log寫起來其實還蠻費勁的;如果能把boost.log導進來的話,不僅輸出log的時候會更方便,而且又能夠利用boost.log本身上提供的許多強大的功能。

其實boost.log還蠻容易跟其他引擎做結合的,我們只需要寫一個backend,並將其所綁定的sink加入到boost.log系統裡面就行了。而這個backend要做的事情也很簡單,它只需要負責把傳進來的訊息再原封不動的傳給UE4原本的log系統。聽起來是不是很簡單?先讓我們來看一下下面這段code:

https://gist.github.com/dorgonman/fdab8f1be4a11a4a4fbc

把sink加入到log系統的方式如下:

typedef boost::log::sinks::synchronous_sink<HorizonLogBasicFormatedBackend> HorizonLogSink;

boost::log::core::get()->add_sink(sink);

紅色的部份是我們自己寫的backend,其實作如下:

https://gist.github.com/dorgonman/3f56b82a8116bddb3425

這個backend留有一個接口:

inline void setLogMessageImplemen(HorizonLogImpFunc_t&& impl);

目的就是留一個log的實作方式給引擎方去設定,我們需要做的就是從UE4丟一個std::function到backend就行了。設定方式如下:

https://gist.github.com/dorgonman/0db4138c2cee95b51582

然後由於UE4中的check macro跟boost中的有衝突,因此在include boost 相關的header之前需先做下面這件事:

#pragma push_macro(“check”)
#undef check
//include your boost header here
#pragma pop_macro(“check”)

接下來我們就可以很方便的使用boost所提供的log機制了:

https://gist.github.com/dorgonman/575f2e4a3c78621bcff8

只是目前的機制只能用在64位元的版本中,不知道為什麼當運行起32位元的時候總是會在下面這行code crash:

if (_Myostr.rdbuf() != 0)

再往上追一層可以看到:

sentry guard(*this);

目前還在研究到底發生什麼是,看code似乎是裡面某個typedef std::basic_ostream< char, std::char_traits<char> > ostream_type;在呼叫rdbuf的時候叫到Myostr的dangle reference。

Leave a Reply

Your email address will not be published. Required fields are marked *