gpt4 book ai didi

c++ - 使用 spdlog 从库中记录

转载 作者:可可西里 更新时间:2023-11-01 18:39:32 25 4
gpt4 key购买 nike

我正在尝试使用 spdlog在涉及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;
};

#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");
}

应用

main.cpp

#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;
}

最佳答案

Spdlog 使用单例注册表来跟踪可用的记录器。你得到 one instance每个 dll 和 exe 的那个注册表。

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

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

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

或使用您的代码的示例:

图书馆

库类.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

库类.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);
}

应用 main.cpp

#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;
}

关于c++ - 使用 spdlog 从库中记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30400286/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com