如何使用DLL在应用程序中模仿静态库中全局变量的多个实例的行为?
我们有一个用C/C++编写的应用程序,它被分成单个EXE和多个DLL。这些DLL中的每个都使用相同的静态库(utilities.lib
)。
utilities.lib
已链接到的每个模块(即DLL或EXE)都有一个全局变量副本。
(这都是众所周知的,而且很好,但是有必要回顾一下静态库在DLL上下文中的行为背景。)
现在我的问题是..我们希望将utilities.lib
更改为DLL。它正在变得非常大和复杂,我们希望以DLL形式分发它,而不是.lib
形式。问题是,对于这一个应用程序,我们希望保留每个应用程序DLL在实用程序库中拥有自己的全局变量副本的当前行为。您将如何着手进行这项工作?实际上,我们并不需要为所有全局变量使用它,只需要一些全局变量;但即使我们为所有变量都使用它,也没有关系。
我们的想法:
- 库中没有太多我们关心的全局变量,我们可以用访问器包装每个全局变量,该访问器会尝试找出哪个DLL在调用它。大概我们可以沿着调用堆栈向上搜索每个函数的
HMODULE
,直到找到一个不是utilities.dll
的函数。然后,我们可以根据调用的DLL返回不同的版本。 - 我们可以强制调用者在调用
utilities.dll
中的任何函数之前设置一个特定的全局变量(也可能是线程局部变量)。然后,实用程序DLL可以使用此全局变量值来确定调用上下文。 - 我们可以找到在运行时多次加载
utilities.dll
的方法。也许我们需要在构建时创建多个重命名的副本,以便每个应用程序DLL都可以拥有其自己的实用程序DLL副本。这从一开始就否定了使用DLL的一些优点,但是对于其他应用程序来说,这种"静态库"样式的行为是不需要的,并且仍然可以从utilities.lib
变为utilities.dll
中受益。
解决方案
您最好是拥有实用程序。dll导出其他函数以分配和释放包含变量的结构,然后让其他每个辅助DLL在需要时在运行时调用这些函数,例如在DllEntryPoint()的dll_ATTACH_PROCESS和dll_DETACH_PROCESS阶段。这样,每个DLL都会获得其自己的变量本地副本,并可以将该结构传递回实用程序。dll函数作为一个附加参数。
另一种方法是直接在每个辅助DLL中本地声明各个变量,然后在需要时将它们作为输入/输出参数传递到实用程序.dll中。
无论哪种方式,都没有实用程序。dll会尝试自己找出上下文信息。它不会工作得很好。相关文章