我们有一个用 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
.
最佳答案
您可能最好只是让 utilities.dll 导出附加函数来分配和释放包含变量的结构,然后让您的每个其他工作 DLL 在需要时在运行时调用这些函数,例如在 DLL_ATTACH_PROCESS 和DllEntryPoint() 的 DLL_DETACH_PROCESS 阶段。这样,每个 DLL 都有自己的变量本地拷贝,并且可以将结构作为附加参数传递回 utilities.dll 函数。
另一种方法是直接在每个 worker DLL 中本地声明各个变量,然后在需要时将它们作为输入/输出参数传递到 utilities.dll。
无论哪种方式,都不要让 utilities.dll 尝试自行找出上下文信息。它不会很好地工作。
关于c++ - 如何模仿静态库的 "multiple instances of global variables within the application"行为但使用 DLL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1076644/