具有来自同一 DLL 的全局变量的多个实例

发布于 2024-10-27 10:08:20 字数 3234 浏览 0 评论 0原文

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

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 只会加载一次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 实例?

Currently, I have a system with the following simplified view.

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)

The source code for COMMON.DLL is as follow.

// 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

The source code for DLL0.DLL is as follow.

__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();
}

The source for for DLL1.DLL is as follow.

__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();
}

The source code for EXE is as follow.

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

The output is as follow.

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

The entire system is executed within a single process. Although DLL0.DLL and DLL1.DLL are being loaded explicitly each, the dependency COMMON.DLL will only be loaded once in entire application life cycle. EXE will not load same COMMON.DLL twice.

Is there any way, I can achieve the following without violating one of the rules?

  1. DLL0 and DLL1 can have their own instance of global_variable?
  2. global_variable must be global, and re-inside COMMON.DLL?
  3. COMMON.DLL will be loaded through implicit linking using LIB file.
  4. No renaming COMMON.DLL to COMMON-DLL0.DLL and COMMON-DLL1.DLL.
  5. No static linking.
  6. If DLL0 change the value of global_variable, calling common_fun_which_access_global_variable from DLL0 should access to DLL0's changed value. However, calling common_fun_which_access_global_variable from DLL1 shouldn't realize the changes.

** I know this is too much. But I am now dealing with a legacy code. You know :)

Will side-by-side assembly able to solve this kind of problem? What I understand is that, side-by-side assembly is used to solve multiple DLL with same name but different version issues. I am not sure whether it is applicable in my above case?

Or, should I ask the other way around? How can we have 2 instance of COMMON.DLL being loaded within a same EXE?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

走走停停 2024-11-03 10:08:20

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

在不了解所有细节的情况下,我建议如下:

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

If I understand the situation correctly, COMMON.dll is the legacy code and the legacy code is used by both DLL0.dll and DLL1.dll.

Without knowing all the details I would suggest the following:

1) Create a global variable in DLL0.dll and DLL1.dll.
2) Initialize each global variable from step 1 with COMMON.dll's global_variable value.
3) Use the two new global_variables as needed.

别低头,皇冠会掉 2024-11-03 10:08:20

由于 DLL 每个进程都有一个一致的映像,因此我认为执行您所要求的操作的唯一方法是将 COMMON.dll 移动到每次使用的唯一进程中。这可以通过多种方式完成,具体取决于您可以访问的代码以及您对丑陋的容忍度。

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

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

Since DLLs have a single, consistent image per process the only way I can see to do what you are asking for is to move COMMON.dll into a unique process per use. That could be done in a variety of ways, depending on what code you have access to, and your tolerance for ugliness.

Can your DLL0 and DLL1 be rewritten to interact with your COMMON.dll via a wrapper? If so have the wrapper spawn a separate process to interact with the common.dll. The wrapper then uses some form of IPC (shared memory perhaps) to communicate with the worker process.

Of course, this is far more complicated that just copying the common.dll to a new name...are you sure it's worth the pain?

热情消退 2024-11-03 10:08:20

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

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

(就我而言,我必须运行“DLL0”级别的许多副本,因此编写了一个程序,为我需要的每个实例复制“DLL0”和“COMMON”,然后将“DLL0”副本修补为新名称新名称必须与原始名称的长度相同,并且从记忆中它只是特定名称文本的搜索和替换,尽管从记忆中存在 ANSI 和 WIDE 变体,当然这种方法可能不再有效。 DLL 已签名?)

I had this exact issue, where I had no control over 3rd party DLL0, DLL1 or COMMON.

The solution I created was to duplicate COMMON with different names, and to patch DLL0 and DLL1 to load their own copies.

(in my case, I had to run many copies of the 'DLL0' level, so wrote a program which duplicated the 'DLL0' and 'COMMON' for each instance I needed, then patched the 'DLL0' copies for the new name of COMMON. The new names had to be the same length as the original, and from memory it was just a search and replace of the specific name text, although from memory there were ANSI and WIDE varieties. Of course this approach may no longer work if the DLLs are signed?)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文