Registering with the library using spdlog

I am trying to use spdlog in a project involving a library under windows. I create two registrars. One for the application using the library, one for the library itself. The library registrar is created from the application, but when the library wants to add a message, it fails.

The following is a simplified example.

Library

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

application

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; } 
+7
source share
2 answers

Your example works fine on the current version of 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 

The same when using a shared 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) 

Results:

 $ 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 

Make sure you are connecting to the DLL runtime environment on Windows.

+1
source

Spdlog uses a single registry to track available registrars. You get one copy of this registry on dll and exe.

When you create a registrar in exe, it is added to the exe registry, but not in the dll. When you use spdlog::get(myLoggerName) in your dll, you request a dll registry that does not contain "lib_logger", and thus you get zero shared_ptr.

Possible solutions: Create lib_logger in lib instead of exe if you use it in dll anyway, or pass the logger from exe to dll and call spdlog::register_logger with it inside the dll before calling spdlog::get(myLoggerName) . Then you can use the same registrar from EXE and DLL.

An example of how to register registrars across dll boundaries can be found at https://github.com/gabime/spdlog/wiki/How-to-use-spdlog-in-DLLs

Or an example of using your code:

Library

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 

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

Main.cpp application

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

Source: https://habr.com/ru/post/987759/


All Articles