Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用spdlog从库进行日志记录_C++_Spdlog - Fatal编程技术网

C++ 使用spdlog从库进行日志记录

C++ 使用spdlog从库进行日志记录,c++,spdlog,C++,Spdlog,我正试图在一个涉及windows下的库的项目中使用。 我创建了两个记录器。一个用于使用库的应用程序,一个用于库本身。 库的记录器是从应用程序创建的,但当库想要添加消息时,它会崩溃 下面是一个简化的示例 图书馆 libclass.h #ifndef LIBCLASS_H #define LIBCLASS_H #include <spdlog/spdlog.h> #ifdef WIN32 # ifdef BUILD_APPLIB_SHARED # define APPLIB_

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

下面是一个简化的示例

图书馆

libclass.h

#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
应用程序

main.cpp

#包括
#包括
无效日志测试()
{
自动记录器=spdlog::get(“应用程序记录器”);
记录器->信息(“从应用程序记录”);
}
int main(int argc,char*argv[])
{
//创建记录器
自动应用记录器=spdlog::标准输出记录器(以下简称“应用记录器”);
自动libLogger=spdlog::stdout_logger_mt(LibClass::loggerName());
//从应用程序登录
logtest();
//从库记录
LIB类信用证;
lc.testLog();
返回0;
}

您的示例在spdlog上运行良好:

$ 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

使用共享库时相同:

# 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)
结果:

$ 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运行时链接。

Spdlog使用单例注册表跟踪可用的记录器。不过,您可以通过dll和exe访问该注册表

在exe中创建记录器时,它将添加到exe的注册表中,但不会添加到DLL中。当您在dll中使用
spdlog::get(myLoggerName)
时,您正在查询不包含“lib_logger”的dll的注册表,因此您将获得一个空的共享\u ptr

可能的解决方案是:如果只在dll中使用lib_记录器,则在lib中创建lib_记录器,而不是在exe中创建,或者将记录器从exe传递到dll,并在调用
spdlog::register_logger
之前在dll中注册它。然后您可以从exe和dll使用相同的记录器

有关如何跨dll边界注册记录器的示例,请参见

或使用您的代码的示例:

图书馆

libclass.h

#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
\ifndef LIBCLASS\u H
#定义libu类
#包括
#ifdef WIN32
#ifdef构建应用程序共享
#定义APPLIB_导出declspec(dllexport)
#否则
#定义APPLIB_导出
#endif//BUILD\u APPLIB\u SHARED
#否则
#定义APPLIB_导出
#endif//WIN32
类APPLIB_导出LibClass
{
公众:
LibClass();
~LibClass();
静态std::string loggerName();
void testLog();
私人:
std::共享_ptr m_记录器;
};
APPLIB_导出无效寄存器记录器(std::shared_ptr记录器);
#endif//LIBCLASS_H
libclass.cpp

#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);
}
#包括“libclass.h”
const std::string myLoggerName=“lib_logger”;
LibClass::LibClass()
{
m_logger=spdlog::get(myLoggerName);
}
LibClass::~LibClass()
{ }
std::string LibClass::loggerName()
{
返回myLoggerName;
}
void LibClass::testLog()
{
m_logger->info(“从库中记录”);
}
APPLIB_导出无效寄存器记录器(std::shared_ptr记录器)
{
spdlog::寄存器\记录器(记录器);
}
应用程序 main.cpp

#包括
#包括
#包括
无效日志测试()
{
自动记录器=spdlog::get(“应用程序记录器”);
记录器->信息(“从应用程序记录”);
}
int main(int argc,char*argv[])
{
//创建记录器
自动应用记录器=spdlog::标准输出记录器(以下简称“应用记录器”);
自动libLogger=spdlog::stdout_logger_mt(LibClass::loggerName());
寄存器记录器(libLogger);
//从应用程序登录
logtest();
//从库记录
LIB类信用证;
lc.testLog();
返回0;
}

您的示例之所以有效,是因为所有内容都在同一个二进制文件下。如果您在共享库中构建libclass,并与共享库进行主链接,则它将不起作用。
#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
#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);
}
#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;
}