How to use spdlog in DLLs

How to use spdlog in DLLs

  • 最近想把spdlog放在common.dll里,给serverdll用,好像不行,
  • 一直报错,查了下,应该是spdlog 都是头文件,模板类必须把实现和头文件放一起
1>------ 已启动生成: 项目: SfuServer, 配置: Debug Win32 ------
1>SfuServer.cpp
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\common\slog.h(105,44): warning C4251: “Logger::text_log_”: class“std::shared_ptr<spdlog::logger>”需要有 dll 接口由 class“Logger”的客户端使用
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\third_party\spdlog\include\spdlog\details\registry.h(33): message : 参见“std::shared_ptr<spdlog::logger>”的声明
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\common\slog.h(106,47): warning C4251: “Logger::console_log_”: class“std::shared_ptr<spdlog::logger>”需要有 dll 接口由 class“Logger”的客户端使用
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\third_party\spdlog\include\spdlog\details\registry.h(33): message : 参见“std::shared_ptr<spdlog::logger>”的声明
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\common\bolt_logger.h(38,53): warning C4251: “Bolt::Log::s_CoreLogger”: class“std::shared_ptr<spdlog::logger>”需要有 dll 接口由 class“Bolt::Log”的客户端使用
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\third_party\spdlog\include\spdlog\details\registry.h(33): message : 参见“std::shared_ptr<spdlog::logger>”的声明
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\common\bolt_logger.h(39,55): warning C4251: “Bolt::Log::s_ClientLogger”: class“std::shared_ptr<spdlog::logger>”需要有 dll 接口由 class“Bolt::Log”的客户端使用
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\third_party\spdlog\include\spdlog\details\registry.h(33): message : 参见“std::shared_ptr<spdlog::logger>”的声明
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\common\bolt_logger.h(40,52): warning C4251: “Bolt::Log::s_LuaLogger”: class“std::shared_ptr<spdlog::logger>”需要有 dll 接口由 class“Bolt::Log”的客户端使用
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\third_party\spdlog\include\spdlog\details\registry.h(33): message : 参见“std::shared_ptr<spdlog::logger>”的声明
1>  正在创建库 G:\RRRRRtc\licode-windows-commshare\onlyServer\SfuServer\..\OutDir\Debug\SfuServer.lib 和对象 G:\RRRRRtc\licode-windows-commshare\onlyServer\SfuServer\..\OutDir\Debug\SfuServer.exp
1>SfuServer.obj : error LNK2001: 无法解析的外部符号 "private: static class std::shared_ptr<class spdlog::logger> Bolt::Log::s_CoreLogger" (?s_CoreLogger@Log@Bolt@@0V?$shared_ptr@Vlogger@spdlog@@@std@@A)
1>SfuServer.obj : error LNK2001: 无法解析的外部符号 "private: static class std::shared_ptr<class spdlog::logger> Bolt::Log::s_ClientLogger" (?s_ClientLogger@Log@Bolt@@0V?$shared_ptr@Vlogger@spdlog@@@std@@A)
1>SfuServer.obj : error LNK2001: 无法解析的外部符号 "private: static class std::shared_ptr<class spdlog::logger> Bolt::Log::s_LuaLogger" (?s_LuaLogger@Log@Bolt@@0V?$shared_ptr@Vlogger@spdlog@@@std@@A)
1>G:\RRRRRtc\licode-windows-commshare\onlyServer\SfuServer\..\OutDir\Debug\SfuServer.exe : fatal error LNK1120: 3 个无法解析的外部命令
1>已完成生成项目“SfuServer.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
  • zz 官方

Wambou edited this page on 30 Aug 2018 · 1 revision
Problem

  • Because spdlog is header-only, building shared libraries and using it in a main program will not share the registry between them. This means that calls to functions like spdlog::set_level(spdlog::level::level_enum::info) will not change loggers in DLLs.

官方例子,封装函数解决 Workaround

-What can be done is to register the logger in both registries.

/*
 * Disclaimer:
 *   This was not compiled but extracted from documentation and some code.
 */

// mylibrary.h
// In library, we skip the symbol exporting part  跳过了符号导出

#include <memory>
#include <vector>
#include <spdlog/logger.h>
#include <spdlog/sinks/stdout_color_sinks.h>

namespace library
{
static const std::string logger_name = "example";

std::shared_ptr<spdlog::logger> setup_logger(std::vector<spdlog::sink_ptr> sinks)
{
    auto logger = spdlog::get(logger_name);
    if(not logger)
    {
        if(sinks.size() > 0)
        {
            logger = std::make_shared<spdlog::logger>(logger_name,
                                                      std::begin(sinks),
                                                      std::end(sinks));
            spdlog::register_logger(logger);
        }
        else
        {
            logger = spdlog::stdout_color_mt(logger_name);
        }
    }

    return logger;
}

void test(std::string message)
{
    auto logger = spdlog::get(logger_name);
    if(logger)
    {
        logger->debug("{}::{}", __FUNCTION__, message);
    }
}

}
// In the main program 主程序

#include <mylibrary.h>
#include <spdlog/logger.h>
#include <spdlog/sinks/daily_file_sink.h>
#include <spdlog/sinks/stdout_sinks.h>

int main()
{
    // We assume that we load the library here 在这里加载库
    ...

    // Let's use the library
    std::vector<spdlog::sink_ptr> sinks;
    sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_st>());
    sinks.push_back(std::make_shared<spdlog::sinks::daily_file_sink_st>("logfile", 23, 59));
  //设置
    auto logger = library::setup_logger(sinks);

    spdlog::set_level(spdlog::level::level_enum::debug); // No effect for the library.
    //不打印
    library::test("Hello World!"); // No logging

    spdlog::register_logger(logger);

    // Now this will also affect the library logger
    spdlog::set_level(spdlog::level::level_enum::debug);

   //打印
    library::test("Hello World!"); // Hurray !

    return 0;
}
发布了693 篇原创文章 · 获赞 58 · 访问量 220万+

猜你喜欢

转载自blog.csdn.net/commshare/article/details/105005195