首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用spdlog从库进行日志记录

使用spdlog从库进行日志记录
EN

Stack Overflow用户
提问于 2015-05-22 15:14:00
回答 2查看 24.7K关注 0票数 12

我试图在一个涉及windows下的库的项目中使用木木。我创造了两个伐木者。一个用于使用库的应用程序,一个用于库本身。库的记录器是从应用程序创建的,但是当库想添加消息时,它就崩溃了。

以下是一个简化的示例。

图书馆

libclass.h

代码语言:javascript
运行
复制
#ifndef LIBCLASS_H
#define LIBCLASS_H

#include <spdlog/spdlog.h>

#ifdef WIN32
#  ifdef BUILD_APPLIB_SHARED
#    define APPLIB_EXPORT __declspec(dllexport)
#  else
#    define APPLIB_EXPORT
#  endif //BUILD_APPLIB_SHARED
#else
#  define APPLIB_EXPORT
#endif // WIN32

class APPLIB_EXPORT LibClass
{
public:
    LibClass();
    ~LibClass();

    static std::string loggerName();

    void testLog();

private:
    std::shared_ptr<spdlog::logger> m_logger;
};

#endif //LIBCLASS_H

libclass.cpp

代码语言:javascript
运行
复制
#include "libclass.h"

const std::string myLoggerName = "lib_logger";

LibClass::LibClass()
{
    m_logger = spdlog::get(myLoggerName);
}

LibClass::~LibClass()
{ }

std::string LibClass::loggerName()
{
    return myLoggerName;
}

void LibClass::testLog()
{
    m_logger->info("Log from library");
}

应用程序

main.cpp

代码语言:javascript
运行
复制
#include <spdlog/spdlog.h>
#include <applib/libclass.h>

void logtest()
{
    auto logger = spdlog::get("app_logger");
    logger->info("Log from application");
}

int main(int argc, char *argv[])
{
    // create loggers
    auto appLogger = spdlog::stdout_logger_mt("app_logger");
    auto libLogger = spdlog::stdout_logger_mt(LibClass::loggerName());

    // log from app
    logtest();

    // log from lib
    LibClass lc;
    lc.testLog();

    return 0;
}
EN

回答 2

Stack Overflow用户

发布于 2019-10-18 18:16:59

Spdlog使用单例注册表来跟踪可用的记录器。不过,每个dll和exe都可以获得该注册表的一例

在exe中创建记录器时,它将添加到exe的注册表中,而不是dll。当您在dll中使用spdlog::get(myLoggerName)时,您正在查询不包含"lib_logger“的dll的注册表,因此您将得到一个空shared_ptr。

可能的解决方案是:在库中创建lib_logger,而不是在dll中使用它,或者将记录器从exe传递到dll,并在调用spdlog::get(myLoggerName)之前在dll中调用spdlog::get(myLoggerName)。然后,您可以使用来自exe和dll的相同的记录器。

https://github.com/gabime/spdlog/wiki/How-to-use-spdlog-in-DLLs中可以找到一个如何跨dll边界注册记录器的示例。

或者使用代码的示例:

图书馆

libclass.h

代码语言:javascript
运行
复制
#ifndef LIBCLASS_H
#define LIBCLASS_H

#include <spdlog/spdlog.h>

#ifdef WIN32
#  ifdef BUILD_APPLIB_SHARED
#    define APPLIB_EXPORT __declspec(dllexport)
#  else
#    define APPLIB_EXPORT
#  endif //BUILD_APPLIB_SHARED
#else
#  define APPLIB_EXPORT
#endif // WIN32

class APPLIB_EXPORT LibClass
{
public:
  LibClass();
  ~LibClass();

  static std::string loggerName();

  void testLog();

private:
  std::shared_ptr<spdlog::logger> m_logger;
};

APPLIB_EXPORT void registerLogger(std::shared_ptr<spdlog::logger> logger);

#endif //LIBCLASS_H

libclass.cpp

代码语言:javascript
运行
复制
#include "libclass.h"

const std::string myLoggerName = "lib_logger";

LibClass::LibClass()
{
  m_logger = spdlog::get(myLoggerName);
}

LibClass::~LibClass()
{ }

std::string LibClass::loggerName()
{
  return myLoggerName;
}

void LibClass::testLog()
{
  m_logger->info("Log from library");
}

APPLIB_EXPORT void registerLogger(std::shared_ptr<spdlog::logger> logger)
{
  spdlog::register_logger(logger);
}

应用程序 main.cpp

代码语言:javascript
运行
复制
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_sinks.h>

#include <applib/libclass.h>

void logtest()
{
  auto logger = spdlog::get("app_logger");
  logger->info("Log from application");
}

int main(int argc, char* argv[])
{
  // create loggers
  auto appLogger = spdlog::stdout_logger_mt("app_logger");
  auto libLogger = spdlog::stdout_logger_mt(LibClass::loggerName());

  registerLogger(libLogger);

  // log from app
  logtest();

  // log from lib
  LibClass lc;
  lc.testLog();

  return 0;
}
票数 6
EN

Stack Overflow用户

发布于 2015-08-24 14:30:06

您的示例在spdlog的当前版本上工作得很好:

代码语言:javascript
运行
复制
$ g++ -std=c++11 main.cpp libclass.cpp  -I .
$ ./a.out 
[2015-08-24 07:29:04.502] [app_logger] [info] Log from application
[2015-08-24 07:29:04.502] [lib_logger] [info] Log from library

在使用共享库时相同:

代码语言:javascript
运行
复制
# CMake config:
project(TEST)
include_directories(.)
add_library(class SHARED libclass.cpp)
target_compile_options(class PUBLIC -std=c++11)
add_executable(main main.cpp)
target_link_libraries(main class)

结果:

代码语言:javascript
运行
复制
$ cmake .
$ make 
$ ldd main
    ...
    libclass.so => ...
$ ./main 
[2015-08-25 08:57:51.864] [app_logger] [info] Log from application
[2015-08-25 08:57:51.864] [lib_logger] [info] Log from library

确保链接到Windows上的DLL运行时。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30400286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档