首先,我将展示我的问题,然后提供更多背景细节:
我的问题
- 在 DLL 模块中定义全局对象是个好主意吗?
- 无论如何,我应该如何确保在主机程序中调用 main() 函数之前构造 DLL 模块中的全局对象?
背景
我在Windows平台上的一个Visual C++项目中工作(但同时我们需要保证我们的源代码的跨平台能力以支持 Linux)。
我的一位同事被要求设计和实现一些可以由其他项目共享的独立 DLL 模块。他计划开发两个不同用途的DLL:
- DLL#1 - 一个接口管理器模块,看起来像一个简化的 COM。该 DLL 将包含一个管理实用程序类的所有工厂的 C++ 类。
- DLL#2 - 所有实用程序类及其相应工厂类的容器。
他对这种设计的考虑包括:
- COM 不是跨平台的。此外,COM 对我们的项目环境来说有点过于复杂,所以他设计了这个 Simplified COM 库。
- 他没有将所有东西都放在一个 DLL 中,因为他认为这个简化的 COM 库是非常独立的,不应该与诸如“XML 解析器”之类的实用程序类混合。我同意这一点。
- 所有实用程序类都有其相应的工厂类。我的同事在 DLL#2 的 .cpp 文件中为每个工厂类定义了一个全局对象,并编写了一些棘手的代码让它们注册到 Simplified COM 库。他的意图是:全局对象应该在宿主程序中的main()函数被调用之前构建,并在构建过程中将它们注册到简化的COM中,这样宿主程序就可以创建实用程序类的实例。进入main()。这种行为与 COM 非常相似。我同意这一点,但正如我在“我的问题”部分中提到的那样,我的问题也会出现。
事实上,通过一些实际测试,我们发现这些全局对象无法按意图构建,可悲的是,这让他心碎;-)。但我认为他的设计看起来仍然不错,所以我们想找出一些方法让它发挥作用。我们更愿意以这种方式使用这些 DLL:这些 DLL 与库和包含一起部署在开发人员的计算机中。然后在一个具体的 VC++ 项目中,它们在链接时被合并。现在我们没有编译或链接错误,只是 DLL #2 中的这些全局对象没有按需要创建。