gpt4 book ai didi

c++ - 如何在宿主程序调用 main() 函数之前构造 DLL 模块中的全局对象?

转载 作者:太空宇宙 更新时间:2023-11-04 12:02:32 25 4
gpt4 key购买 nike

首先我会展示我的问题,然后我会提供更多背景细节:

我的问题

  1. 在 DLL 模块中定义全局对象是个好主意吗?
  2. 无论如何,我应该如何确保在宿主程序中调用 main() 函数之前构建 DLL 模块中的全局对象?

背景

我在Windows平台上的一个Visual C++项目中工作(但同时我们需要保证我们的源代码的跨平台能力< strong>支持 Linux)。

我的一位同事被要求设计和实现一些可以由其他项目共享的独立 DLL 模块。他计划开发两个具有不同目的的 DLL:

  1. DLL#1 - 一个接口(interface)管理器模块,看起来像一个简化的 COM。此 DLL 将包含一个 C++ 类,用于管理实用程序类的所有工厂。
  2. DLL#2 - 所有实用程序类及其相应工厂类的容器。

他对这种设计的考虑包括:

  1. COM 不能跨平台。此外,COM 对于我们的项目环境来说有点过于复杂,因此他设计了这个简化的 COM 库。
  2. 他没有把所有东西都放在一个 DLL 中,因为他认为这个 Simplified COM 库是非常独立的,不应该与诸如“XML 解析器”之类的实用类混合使用。我同意这一点。
  3. 所有实用程序类都有相应的工厂类。我的同事在 DLL#2 的 .cpp 文件中为每个工厂类定义了一个全局对象,并编写了一些棘手的代码让它们注册到 Simplified COM 库。他的意图是:在调用宿主程序中的main()函数之前构造全局对象,并在构造过程中将它们注册到Simplified COM,以便宿主程序可以在它创建工具类的实例时立即创建它们。进入 main()。此行为与 COM 非常相似。我同意这一点,但正如我在“我的问题”部分中提到的那样,我的问题也出现了。

事实上,通过一些真实的测试,我们发现这些全局对象无法按预期构建,遗憾的是,这让他心碎了 ;-)。但我认为他的设计看起来仍然不错,所以我们想找出一些方法让它发挥作用。我们更愿意以这种方式使用这些 DLL:DLL 使用 libs 和 include 部署在开发人员的计算机中。然后在具体的 VC++ 项目中,它们在链接时合并。现在我们没有编译或链接错误,只是 DLL #2 中的这些全局对象没有按要求创建。

最佳答案

你不能使用 DLL 的 DllMain()功能来初始化一切?只需检查 DLL_PROCESS_ATTACH,它会让您知道 DLL 是否正在加载。同样,您可以使用 DLL_PROCESS_DETACH 执行任何清理工作。

如果您对 Linux 保持开放,您还可以使用 GCC 的 __attribute__((constructor)) .

关于您的问题:

  1. 在可执行文件中使用全局变量是个好主意。这是否是一个“好”想法完全是主观的。我个人尽可能避免全局变量,因为它简化了事情(更少的意大利面条代码;将引用/对象作为参数传递使依赖关系清晰;更少的线程问题;等等)。我不能肯定地说"is"或“否”,因为我不完全了解您的用例。一个例子会有所帮助。
  2. 我不明白为什么需要在 main() 函数之前创建它们。如果你能保证它们是在 DllMain() 中创建的,它将在 DLL 中的任何其他函数之前被调用(并且用户不调用它;操作系统调用它),你是否真的需要它在 main() 之前吗?我会很惊讶。

关于c++ - 如何在宿主程序调用 main() 函数之前构造 DLL 模块中的全局对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13550769/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com