如何模仿静态库中的“应用程序内的全局variables的多个实例”行为,但使用DLL?

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

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

(这是众所周知的,但是值得深入探讨静态库在DLL上下文中的行为。

现在我的问题..我们要改变utilities.lib ,使它成为一个DLL。 它变得非常庞大和复杂,我们希望以DLLforms而不是.libforms分发它。 问题是,对于这个应用程序,我们希望保留当前的行为,即每个应用程序DLL都拥有公用程序库中全局variables的副本。 你怎么去做这个? 其实我们并不需要所有的全局variables,只有一些; 但是,如果我们能够得到它,那也无所谓。


我们的想法:

  1. 在我们关心的库中没有太多的全局variables,我们可以用一个访问器来包装每个variables,这个访问器会尝试找出哪个DLL正在调用它。 据推测,我们可以走上调用堆栈,并找出每个函数的HMODULE ,直到find一个不是utilities.dll 。 然后我们可以根据调用的DLL返回不同的版本。
  2. 在调用utilities.dll任何函数之前,我们可以要求调用者设置一个特定的全局variables(也可能是线程本地的)。 实用程序DLL然后可以使用此全局variables值来确定调用上下文。
  3. 我们可以find一些在运行时多次加载utilities.dll方法。 也许我们需要在构build时创build多个重命名的副本,以便每个应用程序DLL可以拥有它自己的实用程序DLL副本。 这首先否定了使用DLL的一些优点,但也有其他应用程序不需要这种“静态库”风格的行为,哪些仍然将受益于utilities.lib成为utilities.dll

Solutions Collecting From Web of "如何模仿静态库中的“应用程序内的全局variables的多个实例”行为,但使用DLL?"

你可能最好只是让utilities.dll导出额外的函数来分配和释放一个包含变量的结构,然后在需要的时候让你的其他worker DLL在运行时调用这些函数,比如在DLL_ATTACH_PROCESS和DLL_DETACH_PROCESS阶段的DllEntryPoint()。 这样,每个DLL都获得自己的变量的本地副本,并可以将结构作为附加参数传递回utilities.dll函数。

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

无论哪种方式,没有utilities.dll尝试找出自己的上下文信息。 它不会工作得很好。

如果我这样做,我会分解所有有状态的全局变量 – 我会导出一个COM对象或一个简单的C ++类,其中包含所有必要的状态,每个DLL导出将成为您的类的方法。

解答您的具体问题:

  1. 你不能可靠地做一个这样的堆栈跟踪 – 由于优化,如尾调用优化或FPO你不能确定谁在任何情况下调用你。 你会发现你的程序将在调试中工作,主要是在发布,但偶尔会崩溃。
  2. 我认为你会发现这很难管理,而且它也要求你的库不能与你的进程中的其他模块重入 – 例如,如果你支持回调或事件到其他模块。
  3. 这是可能的,但是你完全否定了使用DLL的要点。 您可以复制到不同的目录并通过完整路径加载,而不是重命名。