我们有一个由许多单独的C ++项目组成的产品 - 直到最近它们都是DLL项目(可执行文件除外)。
其中一些项目从未真正改变过,我们认为通过从日常解决方案中删除这些项目,我们可以减少一些开销。然后将它们更改为构建为静态库,我们可以为开发人员提供链接的.libs(以及PDB等)。
但是,在这个过程中,我们已经破坏了我们的记录器 - 它现在存在于其中一个静态库中。它被声明为全局,我们现在创建了许多实例,而不是像以前那样创建单个实例(当它驻留在DLL项目中时)。拥有许多实例的主要问题是可执行项目通常设置文件名 - 因此文件名仅设置为与可执行项目关联的实例而不是记录器的所有其他实例(即,未记录其他项目的登录)在日志文件中。)
我理解为什么会这样,但我有兴趣从这里获得最好的前进方式。
我认为,最简单的方法是简单地将该特定项目还原为DLL项目。但是,我不想这样做,因为项目也包含其他内容。
我们可以将记录器移动到一个新的DLL项目中 - 这可能相当简单,但我不禁觉得有一个'更好'的解决方案(我想总有:P)。
就代码而言,在我们更改之前,记录器在cpp:
中声明如下static FileLogger m_fileLogger;
标题(包含在所有其他项目的PCH中)有一个宏,它使用全局函数与 m_fileLogger 进行交互。
我不确定为什么声明 static 。
我已经在标题中尝试 externing ,但这并没有改变行为(正如预期的那样,假设在logger的项目中设置了DLL项目静态链接)。
答案 0 :(得分:0)
问题是每个dll都会加载tge静态库,因此代码多次出现。你的记录器包括在内。请记住,静态库只是.obj文件的集合。
唯一的解决方案是将任何公共代码分解为一个公共dll,并在整个过程中使用它,但不止一次地使用静态库非常浪费,并导致您用全局变量描述的问题。
当dll将所有代码和静态数据加载到自己的页面中时。即使它源自相同的.lib,也不会尝试对相同的编码进行重复数据删除。
当谈到静态(全局)数据时,每个dll将保持自己的集合。唯一的解决方案是在一个公共dll中有一个副本。否则你会遇到问题。