2011-03-29 37 views
1

目前,我有一个系统,具有以下简化视图。具有来自同一DLL的全局变量的多个实例

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.DLLCOMMON-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实例?

+1

对,它太多了。你无法完成这项工作。放弃子弹4 – 2011-03-29 03:25:14

回答

2

如果我正确理解这种情况,COMMON.dll是遗留代码,DLL0.dll和DLL1.dll都使用遗留代码。

不知道所有的细节,我建议如下:

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

+0

Opps。抱歉。我忘记了另一个要求。 COMMON也可以看到DLL对global_variable所做的更改。因此,在DLL中有2个独立的全局变量将违反此规则。我修改我的问题。 – 2011-03-29 03:18:57

1

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

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

当然,这是复杂得多,只是将common.dll复制到一个新的名字......你确定它是值得的痛苦?

+0

一年前提问这个问题,查看接受的答案,并考虑评论。 (尽管评论需要50声望。) – vgoff 2012-11-03 20:28:26

0

我有这个确切的问题,我没有控制第三方DLL0,DLL1或COMMON。

我创建的解决方案是用不同的名称复制COMMON,并修补DLL0和DLL1以加载它们自己的副本。 (我的情况下,我不得不运行'DLL0'级别的许多副本,所以写了一个程序,它为我需要的每个实例复制'DLL0'和'COMMON',然后修补'DLL0'副本COMMON的新名称,新名称的长度必须与原始文件的长度相同,从内存来看,它只是搜索和替换特定名称的文本,尽管内存中存在ANSI和WIDE变种。如果DLL被签名,将不再工作?)

相关问题