日志库EasyLogging++学习系列(11)—— 共享日志库

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/Fish_55_66/article/details/49659825

在前面的学习系列文章中,我们都是在单独的一个应用程序中使用 Easylogging++ 日志库。其实 Easylogging++ 日志库是可以共享给动态库、静态库以及应用程序共同使用的。在编写一些大型程序的时候,我们往往会把各个功能分别封装成一个动态库,然后再编写一个主程序来负责调用这些动态库就可以了。现在假设我们想在主程序和各个动态库中都使用 Easylogging++ 来记录日志,那么我们需要在主程序和各个动态库中的代码中都包含 Easylogging++ 的头文件,然后再分别设置主程序和各个动态库的日志配置。这是一个非常繁琐的事情,而且很容易把主程序和各个动态库中的日志配置成保存在同一个文件里,这可能会造成多个动态库同时对同一个日志文件进行写操作的情形,从而可能会使得日志内容乱成一团。但是因为主程序和各个动态库合并起来才算是一个完整的程序,我们又确实想把主程序和各个动态库中相同级别的的日志都保存在同一个文件中,那么我们只需要使用 Easylogging++ 的共享功能,就可以完美地满足我们的需求,并且还能避免上述所说的问题。


在 Easylogging++ 日志库的源码中,有一个名为 Storage 的类,这个类是负责维护 Easylogging++ 日志库数据的主要入口,比如日志记录器的管理,日志配置的管理等都是在 Storage 类中完成的。默认情况下,我们每调用一次初始化宏 INITIALIZE_EASYLOGGINGPP 就会创建一个 Storage 类对象,所以不同的程序就会有不同的 Storage 类对象在负责维护相应的日志记录器和日志配置。如果我们只创建一次 Storage 类对象,然后再将这个对象共享给其他使用 Easylogging++ 日志库的程序使用,那么就可以保证所有程序都在使用同一个 Storage 类对象维护的日志记录器和日志配置,如同在单独的应用程序中使用日志记录一样方便和安全。


为了使用共享的 Storage 类对象,在其他程序中我们不能用宏 INITIALIZE_EASYLOGGINGPP 来初始化日志库,应该改用以下两个宏定义中任意一个:

  •  INITIALIZE_NULL_EASYLOGGINGPP
  • SHARE_EASYLOGGINGPP
如果使用宏 INITIALIZE_NULL_EASYLOGGINGPP ,那么必须用函数 el::Helpers::setStorage(el::base::type::StoragePointer) 来设置共享的 Storage 类对象,否则将会运行出错;如果使用宏 SHARE_EASYLOGGINGPP ,那么必须将共享的 Storage 类对象作为参数传递进去。在 Easylogging++ V9.80 的版本中,如果使用宏 SHARE_EASYLOGGINGPP 编译会出现错误,提示无法解析的外部符号,下面是定义该宏的源码:
#define SHARE_EASYLOGGINGPP(initializedStorage)\
    namespace el {\
        namespace base {\
            el::base::type::StoragePointer elStorage(initializedStorage);\
        }\
        el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
    }
解决编译出错的方法很简单,增加一个宏 ELPP_INITI_BASIC_DECLR 即可,下面是修改之后的代码:
#define SHARE_EASYLOGGINGPP(initializedStorage)\
	ELPP_INITI_BASIC_DECLR\
    namespace el {\
        namespace base {\
            el::base::type::StoragePointer elStorage(initializedStorage);\
        }\
        el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\
    }
其实,修改之后的代码就和另外一个宏   ELPP_INIT_EASYLOGGINGPP 的代码一模一样。有兴趣的小伙伴可以查看一下源码分别了解一下以下几个和初始化有关的宏定义:
  • INITIALIZE_EASYLOGGINGPP
  • ELPP_INIT_EASYLOGGINGPP
  • INITIALIZE_NULL_EASYLOGGINGPP
  • SHARE_EASYLOGGINGPP

最后通过一个完整的演示工程来说明如何只创建一个 Storage 类对象,然后再将该对象共享给其他工程使用。在演示工程有下面四个项目:

  • ShareEasylogging++项目,一个动态库工程,完成 Storage 类对象的创建,并提供获取该对象的接口,以便其他工程共享该对象。
  • ShareEasyloggingDll1项目,一个动态库工程,演示了如何使用宏 SHARE_EASYLOGGINGPP 和共享的 Storage 类对象完成初始化。
  • ShareEasyloggingDll2项目,一个动态库工程,演示了如何使用宏 SHARE_EASYLOGGINGPP 和共享的 Storage 类对象完成初始化。
  • ShareEasyloggingTest项目,演示工程主程序,演示了如何使用宏 INITIALIZE_NULL_EASYLOGGINGPP 和共享的 Storage 类对象完成初始化。

完整的演示工程代码下载:猛戳这里


猜你喜欢

转载自blog.csdn.net/Fish_55_66/article/details/49659825