【问题标题】:How to refactor global logger that now resides in a static library?如何重构现在驻留在静态库中的全局记录器?
【发布时间】:2016-11-01 08:48:43
【问题描述】:

我们的产品由许多单独的 C++ 项目组成 - 直到最近它们都是 DLL 项目(可执行文件除外)。

其中一些项目从未真正改变过,我们认为可以通过从我们的日常解决方案中删除这些项目来减少开发人员产生的一些开销。然后将它们更改为构建为静态库,我们可以为开发人员提供要链接的 .lib(以及 PDB 等)。

不过,在此过程中,我们破坏了我们的记录器——它现在存在于这些静态库之一中。它被声明为全局的,我们现在创建了许多实例,而不是之前的单个实例(当它驻留在 DLL 项目中时)。拥有许多实例的主要问题是可执行项目通常设置文件名 - 因此文件名仅设置为与可执行项目关联的实例,而不是记录器的所有其他实例(即不反映记录其他项目在日志文件中)。

我理解为什么会发生这种情况,但我有兴趣从这里获得最佳前进方向的意见。

我相信,最简单的方法是将特定项目恢复为 DLL 项目。但是,我不希望这样做,因为该项目还包含其他内容。

我们可以将记录器移动到一个新的 DLL 项目中——这将是相当简单的,但我不禁觉得有一个“更好”的解决方案(我想总会有:P)。

在代码方面,在我们更改之前,记录器在 cpp 中声明如下:

static FileLogger m_fileLogger;

标头(包含在所有其他项目的 PCH 中)有一个宏,它使用全局函数与 m_fileLogger 进行交互。

我不知道为什么它被声明为静态

我已经尝试在标题中externing它,但这并没有改变行为(正如预期的那样,考虑到在记录器项目中静态链接的 DLL 项目的设置)。

【问题讨论】:

  • 您可能还可以从那些永不改变的项目中构建 dll 并将其分配(注意所有开发人员都使用相同的 CRT 版本)

标签: c++ logging dll static-libraries


【解决方案1】:

问题是每个 dll 都会加载 tge 静态库,因此代码会重复多次。包括您的记录器。请记住,静态库只是 .obj 文件的集合。

唯一的解决方案是将任何通用代码分解到一个通用 dll 中并在整个过程中使用它,但多次包含静态库是非常浪费的,并且会导致您使用全局变量描述的问题。

当一个 dll 将所有代码和静态数据加载到它自己的页面中时。即使它来自同一个 .lib,也不会尝试对相同的编码进行重复数据删除。

当涉及到静态(全局)数据时,每个 dll 都将拥有自己的集合。唯一的解决方案是在一个通用 dll 中拥有一个副本。否则你会遇到问题。

【讨论】:

  • 正如我所说 - 我理解为什么会出现问题。您是说将多个项目链接到静态库是浪费吗?你能详细说明一下吗?
  • 我已经扩展回答。希望对你有帮助
  • 感谢@doron,通过这种方法,我会将记录器移动到一个新的 DLL 项目中(该项目中的其他内容不需要在 dll 中)。我将把这个问题留得更久一些,以防其他人提出不同的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
  • 2011-12-11
相关资源
最近更新 更多