如何使用DLL在应用程序中模仿静态库中全局变量的多个实例的行为?

2022-04-08 00:00:00 windows dll c c++ static-libraries

我们有一个用C/C++编写的应用程序,它被分成单个EXE和多个DLL。这些DLL中的每个都使用相同的静态库(utilities.lib)。

实用程序静态库中的任何全局变量在运行时实际上都会在应用程序中拥有多个实例。utilities.lib已链接到的每个模块(即DLL或EXE)都有一个全局变量副本。

(这都是众所周知的,而且很好,但是有必要回顾一下静态库在DLL上下文中的行为背景。)

现在我的问题是..我们希望将utilities.lib更改为DLL。它正在变得非常大和复杂,我们希望以DLL形式分发它,而不是.lib形式。问题是,对于这一个应用程序,我们希望保留每个应用程序DLL在实用程序库中拥有自己的全局变量副本的当前行为。您将如何着手进行这项工作?实际上,我们并不需要为所有全局变量使用它,只需要一些全局变量;但即使我们为所有变量都使用它,也没有关系。


我们的想法:

  1. 库中没有太多我们关心的全局变量,我们可以用访问器包装每个全局变量,该访问器会尝试找出哪个DLL在调用它。大概我们可以沿着调用堆栈向上搜索每个函数的HMODULE,直到找到一个不是utilities.dll的函数。然后,我们可以根据调用的DLL返回不同的版本。
  2. 我们可以强制调用者在调用utilities.dll中的任何函数之前设置一个特定的全局变量(也可能是线程局部变量)。然后,实用程序DLL可以使用此全局变量值来确定调用上下文。
  3. 我们可以找到在运行时多次加载utilities.dll的方法。也许我们需要在构建时创建多个重命名的副本,以便每个应用程序DLL都可以拥有其自己的实用程序DLL副本。这从一开始就否定了使用DLL的一些优点,但是对于其他应用程序来说,这种"静态库"样式的行为是不需要的,并且仍然可以从utilities.lib变为utilities.dll中受益。

解决方案

您最好是拥有实用程序。dll导出其他函数以分配和释放包含变量的结构,然后让其他每个辅助DLL在需要时在运行时调用这些函数,例如在DllEntryPoint()的dll_ATTACH_PROCESS和dll_DETACH_PROCESS阶段。这样,每个DLL都会获得其自己的变量本地副本,并可以将该结构传递回实用程序。dll函数作为一个附加参数。

另一种方法是直接在每个辅助DLL中本地声明各个变量,然后在需要时将它们作为输入/输出参数传递到实用程序.dll中。

无论哪种方式,都没有实用程序。dll会尝试自己找出上下文信息。它不会工作得很好。

相关文章