【问题标题】:Having multiple instance of global variables from same DLL具有来自同一 DLL 的多个全局变量实例
【发布时间】:2011-07-24 22:38:43
【问题描述】:

目前,我有一个具有以下简化视图的系统。

The entire system run under single process
------------------------------------------
       --- DLL0.DLL --- COMMON.DLL (contains global_variable in COMMON.DLL)
EXE ---|
       --- DLL1.DLL --- COMMON.DLL (contains global_variable in COMMON.DLL)

COMMON.DLL的源代码如下。

// COMMON.DLL
#ifdef COMMON_EXPORTS
_declspec( dllexport ) int global_variable = 100;
// Function used to access and print global_variable.
__declspec(dllexport) void common_fun_which_access_global_variable();
#else
_declspec(dllimport) int global_variable;
__declspec(dllimport) void common_fun_which_access_global_variable();
#endif

DLL0.DLL的源代码如下。

__declspec(dllexport)
void DLL0() {
    printf ("This is DLL0\n");
    printf ("In DLL0, global_variable is %i\n", global_variable);
    common_fun_which_access_global_variable();
    global_variable = 200;
    printf ("DLL0 is now setting global_variable to 200\n");
    common_fun_which_access_global_variable();
}

DLL1.DLL的源码如下。

__declspec(dllexport)
void DLL1() {
    printf ("This is DLL1\n");
    printf ("In DLL1, global_variable is %i\n", global_variable);
    common_fun_which_access_global_variable();
    global_variable = 400;
    printf ("DLL1 is now setting global_variable to 400\n");
    common_fun_which_access_global_variable();
}

EXE源代码如下。

HINSTANCE instance0 = AfxLoadLibrary(_T("DLL0.dll"));
FARPROC fun0 = GetProcAddress(instance0, "DLL0");
HINSTANCE instance1 = AfxLoadLibrary(_T("DLL1.dll"));
FARPROC fun1 = GetProcAddress(instance1, "DLL1");
_fun0();
_fun1();

输出如下。

This is DLL0
In DLL0, global_variable is 100
In COMMON, global_varialbe is 100
DLL0 is now setting global_variable to 200
In COMMON, global_varialbe is 200

This is DLL1
In DLL1, global_variable is 200    <-- I wish 100 is being printed.
In COMMON, global_varialbe is 200  <-- I wish 100 is being printed here too.
                                   <-- I wish DLL0 and DLL1 have their own instance of
                                   <-- global_variable respectively.
DLL1 is now setting global_variable to 400
In COMMON, global_varialbe is 400

整个系统在单个进程中执行。尽管DLL0.DLLDLL1.DLL 都被显式加载,但依赖关系COMMON.DLL 在整个应用程序生命周期中只会被加载一次。 EXE 不会加载相同的COMMON.DLL 两次。

有什么办法,我可以在不违反任何一条规则的情况下实现以下目标?

  1. DLL0 和 DLL1 可以有自己的 global_variable 实例?
  2. global_variable 必须是全局的,并且重新在 COMMON.DLL 内部?
  3. COMMON.DLL 将通过使用 LIB 文件的隐式链接加载。
  4. 不能将COMMON.DLL 重命名为COMMON-DLL0.DLLCOMMON-DLL1.DLL
  5. 没有静态链接。
  6. 如果 DLL0 更改了 global_variable 的值,从 DLL0 调用 common_fun_which_access_global_variable 应该可以访问 DLL0 的更改值。但是,从 DLL1 调用 common_fun_which_access_global_variable 应该不会实现这些更改。

** 我知道这太过分了。但我现在正在处理遗留代码。你知道:)

并排组装能够解决此类问题吗?我的理解是,并行程序集用于解决多个同名但版本不同的 DLL 问题。我不确定它是否适用于我的上述情况?

或者,我应该反过来问吗?我们如何在同一个 EXE 中加载 2 个 COMMON.DLL 实例?

【问题讨论】:

  • 对,太多了。你不能让这个工作。放弃第 4 条

标签: c++ windows visual-c++ dll


【解决方案1】:

如果我理解正确的话,COMMON.dll 是遗留代码,DLL0.dll 和 DLL1.dll 都使用遗留代码。

在不知道所有细节的情况下,我会建议以下内容:

1) 在 DLL0.dll 和 DLL1.dll 中创建一个全局变量。
2) 使用 COMMON.dll 的 global_variable 值初始化步骤 1 中的每个全局变量。
3) 根据需要使用两个新的 global_variables。

【讨论】:

  • 奥普斯。对不起。我忘记了另一个要求。 DLL 对 global_variable 所做的更改也应该对 COMMON 可见。因此,在 DLL 中有 2 个单独的全局变量将违反此规则。我修改了我的问题。
【解决方案2】:

由于 DLL 的每个进程都有一个单一的、一致的图像,我能看到的唯一方法是按照您的要求将 COMMON.dll 移动到一个唯一的进程中。这可以通过多种方式完成,具体取决于您可以访问的代码以及您对丑陋的容忍度。

您的 DLL0 和 DLL1 能否被重写以通过包装器与您的 COMMON.dll 交互?如果是这样,让包装器生成一个单独的进程来与 common.dll 交互。然后包装器使用某种形式的 IPC(可能是共享内存)与工作进程通信。

当然,这比将 common.dll 复制到一个新名称要复杂得多……你确定这值得吗?

【讨论】:

  • 这个问题是一年前提出的,检查接受的答案,并考虑对此发表评论。 (不过 cmets 需要 50 声望。)
【解决方案3】:

我遇到了这个确切的问题,我无法控制第 3 方 DLL0、DLL1 或 COMMON。

我创建的解决方案是使用不同的名称复制 COMMON,并修补 DLL0 和 DLL1 以加载它们自己的副本。

(在我的情况下,我必须运行“DLL0”级别的许多副本,因此编写了一个程序,为我需要的每个实例复制“DLL0”和“COMMON”,然后修补“DLL0”副本以用于COMMON 的新名称。新名称的长度必须与原始名称相同,并且从记忆中它只是对特定名称文本的搜索和替换,尽管记忆中有 ANSI 和 WIDE 变体。当然这种方法可能没有如果 DLL 已签名,则工作时间更长?)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多