0

私はこれをやろうとしました: Boost::Log を使用する Windows (*.dll) で 1 つの共有ライブラリを作成します ( Boost::Log をこのライブラリに静的にリンクしたいのは、すべてを 1 つの DLL ファイルだけにパッケージ化したいからです)。うまくいきませんでした

私のプロジェクトには、次の 4 つのファイルがあります。

私のCMakeLists.txt:(Boostライブラリを見つける別のCMakeLists.txtがありますfind_package(Boost 1.54.0 REQUIRED thread log log_setup filesystem date_time system)

cmake_minimum_required(VERSION 2.6)

add_library(mylog SHARED
  mylog.cpp
  )
target_link_libraries(mylog ${Boost_LIBRARIES})

if(UNIX)
  target_link_libraries(mylog rt)
endif(UNIX)

add_executable(testlog
  main.cpp
  )
target_link_libraries(testlog mylog)

私のmylog.cpp :

#include "mylog.h"

namespace logging = boost::log;
namespace expr = boost::log::expressions;
namespace keywords = boost::log::keywords;

__declspec( dllexport ) void initLog()
{
    logging::add_file_log(
    keywords::file_name = "testlog.log",    
    keywords::format = expr::format("%1% [%2%] %3% ")
        % expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d, %H:%M:%S.%f")
        % expr::attr< logging::trivial::severity_level >("Severity")
        % expr::smessage
    );

    logging::add_common_attributes();
}

そしてmylog.h :

#ifndef _MYLOG_H
#define _MYLOG_H

#include <boost/log/common.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/log/utility/empty_deleter.hpp>

__declspec( dllexport ) void initLog();

#endif //_MYLOG_H

私のmain.cpp :

#include "mylog.h"

int main(int, char*[])
{
    using namespace boost::log::trivial;
    initLog();
    BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
    BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
    BOOST_LOG_TRIVIAL(info) << "An informational severity message";
    BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
    BOOST_LOG_TRIVIAL(error) << "An error severity message";
    BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";    
    return 0;
}

ライブラリmylog静的なもの (SHARED キーワードなし) としてコンパイルし、プログラムtestlogを実行すると、ログ メッセージがファイルtestlog.logに保存され、コードが示すように画面に何も出力されません。

2013-12-20, 15:05:36.741156 [trace] A trace severity message         
2013-12-20, 15:05:36.742156 [debug] A debug severity message         
2013-12-20, 15:05:36.743156 [info] An informational severity message 
2013-12-20, 15:05:36.743156 [warning] A warning severity message     
2013-12-20, 15:05:36.743156 [error] An error severity message        
2013-12-20, 15:05:36.743156 [fatal] A fatal severity message         

しかし、 (SHARED キーワードを使用して) DLL共有ライブラリにコンパイルすると、コンパイルは成功しましたが、結果は期待どおりではありませんでした。ログ ファイルは作成されず、メッセージは異なる形式で画面に表示されました。関数initLogが実行されていないようです:

[2013-12-20 15:06:17.195469] [0x00000e6c] [trace]   A trace severity message          
[2013-12-20 15:06:17.198470] [0x00000e6c] [debug]   A debug severity message          
[2013-12-20 15:06:17.198470] [0x00000e6c] [info]    An informational severity message 
[2013-12-20 15:06:17.199470] [0x00000e6c] [warning] A warning severity message        
[2013-12-20 15:06:17.199470] [0x00000e6c] [error]   An error severity message         
[2013-12-20 15:06:17.200470] [0x00000e6c] [fatal]   A fatal severity message          

これについて私を助けてください。ありがとう。

P/S: Boost::Log::Trivial を使用せずに、ロギング用のカスタム シンクを作成しようとしましたが、結果は同じです。Boost 1.54.0 と 1.55.0 の両方がテストされています。

4

2 に答える 2

1

boost::log動的リンクをサポートするには、適切に構成してビルドする必要があるようです。それ以外の場合は、静的リンク モデルを想定します。

ドキュメントはこちら: http://boost-log.sourceforge.net/libs/log/doc/html/log/installation/config.html

関連する引用:

ライブラリには、Getting Started guideの説明に従ってビルドする必要がある個別にコンパイルされた部分があります。ただし、注意すべき点が 1 つあります。アプリケーションが Boost.Log を使用する複数のモジュール (exe と 1 つまたは複数の dll など) で構成されている場合、ライブラリは共有オブジェクトとして構築する必要があります。Boost.Log で動作する単一の実行可能ファイルまたは単一のモジュールがある場合は、ライブラリを静的ライブラリとしてビルドできます。

于 2013-12-20T08:06:47.887 に答える
0

呼び出し側のプロトタイプにdllimport属性が必要です。initLog()慣用的なアプローチは、プリプロセッサの定義を使用して、mylog.h に、それが DLL ビルドから含まれているかどうかを伝えることdllexportですdllimport

mylog.h:

#ifdef BUILD_MYLOG_DLL
#define DLLATTRIBUTE __declspec( dllexport )
#else
#define DLLATTRIBUTE __declspec( dllimport )
#endif

DLLATTRIBUTE void initLog();

CMakeLists.txt:

SET_TARGET_PROPERTIES(mylog PROPERTIES COMPILE_DEFINITIONS "BUILD_MYLOG_DLL")

これで、dllexport は mylog ライブラリをビルドするときにのみ使用され、ファイルを含む他のものは代わりに dllimport を取得します。

静的モードもサポートする場合は、DLLATTRIBUTE を空に定義する BUILD_MYLOG_DLL 句全体に別の条件を追加します。

于 2013-12-20T16:05:05.433 に答える