C++ DLL中全局变量的范围是啥

Posted

技术标签:

【中文标题】C++ DLL中全局变量的范围是啥【英文标题】:What is the scope of global variables inside C++ DLLsC++ DLL中全局变量的范围是什么 【发布时间】:2011-02-05 17:30:52 【问题描述】:

假设第 3 方 DLL X 有一个全局变量 G

我编写了两个独立的 DLL(作为应用程序的插件)P1P2,它们都动态加载 X

应用程序的进程会加载我的两个插件 P1P2,因此它们是同时加载的。

这是否意味着我有一个或两个 G 实例?

编辑:

使用场景是 X 是一个 3D 渲染引擎,它具有封装系统资源的单例,它根本不是为了在一个进程中期望多个实例而设计的 - 你可以运行 2 个 X 的应用程序,但尝试在 same 应用程序中初始化 X 两次会搞砸。 这两个插件都使用 X,但将作为单独的安装程序部署,它们彼此不了解,也不会共享相同的 X。 dll 文件 - 通常每个插件都有自己的目录来存储所需的资源和 DLL。

【问题讨论】:

【参考方案1】:

在 Win32 API 中公开的 DLL 加载例程确保每个进程只加载一个 DLL 副本(see the "Remarks" section here,特别是第三段和安全备注部分之前的最后一段,其中每个进程的引用计数是讨论)。我假设你只是打电话给LoadLibrary 或类似的,在这种情况下你有一个 G 的实例。

似乎认为可以通过在不同位置 (as noted in this sort-of related question) 保存多个有问题的 DLL 副本并加载每个副本来规避此问题,在这种情况下,您可以结束每个 DLL(包括 G)中所有数据的多个副本。

【讨论】:

这是否意味着如果 P1P2静态 链接到 X .lib 相反,现在“问题”消失了吗? @John 什么问题?您想要两个 G 实例吗? @David Heffernan 我想避免不知道 DLL 是否具有全局变量,这可能会导致奇怪的错误。请参阅我对您的回答的评论。 检查我是否理解...如果我正在编写 P1P2 作为应用程序 A 的插件并且每个都安装有它自己的子目录 App\plugins\ 包含额外的 DLL 和资源。现在每个插件都倾向于附带自己的 X 副本,所以在这种情况下似乎会自动生成两个 G 副本? 如果每个插件从它自己的目录加载 X.dll,是的。【参考方案2】:

答案是每个进程中都有一个全局变量实例。这一切都在 MSDN 上进行了解释:Dynamic-Link Library Data

【讨论】:

这可能需要提出一个新问题(?),但是可以您以某种方式在新进程中加载​​ DLL 以强制生成它的“唯一”副本吗?如果某些 3rd-party DLL 使用全局变量,您难道不想有办法避免这个问题吗? @John 你可以这样做。您需要为其创建一个临时副本,以便它具有不同的文件名,然后您将获得 G 的两个实例。虽然它非常不标准。您可能应该通过在堆上分配变量来提出一种更简洁的方法。 如果您将 dll 加载到新进程中,您将拥有两个变量实例。每个进程一个。 @John 您需要在这里更详细地描述您关心的问题。使用全局变量不会自动出错。在某些情况下可以安全使用它们。 @frast 不,John 关心的是单个进程中发生的事情。

以上是关于C++ DLL中全局变量的范围是啥的主要内容,如果未能解决你的问题,请参考以下文章

C++,Visual Studio 2017:从加载的 .dll 中访问 .exe 的全局变量 [重复]

如何从 C# 中的 C++ dll 中的全局变量从函数中获取返回数组?

QLibrary Visual C++ 全局变量

c语言static作用范围是啥呢?

C语言中,宏替换与定义全局变量的区别是啥?

C++ 静态库中的共享全局变量