动态 link 库 (.dll) 中的对象是否跨进程共享
Is Object in dynamic link library(.dll) shared across process
假设我的 .dll 文件中有两个 class 和一个 .c 文件。比如
class MyClass {
private :
int id;
Context* appContext;
static Context* statContext;
public:
a(){
appContext = NULL;
id = -1;
}
void setId(int a){
id = a;
}
void setContext(){
statContext = appContext = new Context();
}
Context* getContext(){
return appContext;
}
Contex* getStaticContex(){
return statContext;
}
int getId(){
return id;
}
}
class Context{
Contex(){};
~Context(){};
}
在我的 .c 文件中,有三个函数通过 dllexport 暴露在 .dll 之外,其中包含
MyClass a;
void dllSetContext(){
a.SetContext();
}
Context* dllGetContext(){
a.getContext();
}
Context* dllGetStaticContext(){
a.getStaticContex();
}
- 现在加载 dll 后的一个进程调用 dllSetContext();
- 另一个进程也加载 dll 并调用 dllGetContext() 和
dllGetStaticContext()。是否获取了appContext的实例,
statContext 由第一个进程设置?
- 是否创建了两个单独的 MyClass 实例,每个单独
每个进程的实例
- 或者这两个进程共享一个 MyClass 实例?
这里我的理解是静态的,全局变量不跨多进程共享,其他的都是多进程共享。
这取决于操作系统如何管理地址space。在现代(32 位)Windows 操作系统中,每个进程都有一个地址。进程之间没有共同点。
这与在 DLL 中创建对象时没有什么不同。您在不同的进程中获得不同的实例。但他们可能获得相同的虚拟地址。请记住,实例的地址仅在加载 DLL 的进程中有效。
当您为 Windows 3.x 编程时,这可能会有所不同,但我怀疑您是否这样做。
编辑 代码段是否以及如何在进程之间共享可以取决于实际O/S。在 WinCE 5.0 中,您有一个共享进程槽。如果 DLL 在 sysgen 期间作为 MODULE 定位,则代码位于对所有进程相同地址范围可见的共享槽中。您在桌面 Windows 上找不到它。
在某些 O/S 中,相同的代码部分可能位于相同的 物理地址 中,但在依赖进程的 虚拟地址中可见 =23=]。但是如果你开发一个应用程序你就不需要考虑它了。代码只是可见的一个过程。当 DLL 的加载地址已被占用时,相同的 DLL 代码可以位于不同的地址。在那种情况下,O/S 将 DLL 重新定位到一个空闲的地址范围。这需要(一点)时间并且可以通过为每个 DLL 设置不同的默认加载地址来调整。
假设我的 .dll 文件中有两个 class 和一个 .c 文件。比如
class MyClass {
private :
int id;
Context* appContext;
static Context* statContext;
public:
a(){
appContext = NULL;
id = -1;
}
void setId(int a){
id = a;
}
void setContext(){
statContext = appContext = new Context();
}
Context* getContext(){
return appContext;
}
Contex* getStaticContex(){
return statContext;
}
int getId(){
return id;
}
}
class Context{
Contex(){};
~Context(){};
}
在我的 .c 文件中,有三个函数通过 dllexport 暴露在 .dll 之外,其中包含
MyClass a;
void dllSetContext(){
a.SetContext();
}
Context* dllGetContext(){
a.getContext();
}
Context* dllGetStaticContext(){
a.getStaticContex();
}
- 现在加载 dll 后的一个进程调用 dllSetContext();
- 另一个进程也加载 dll 并调用 dllGetContext() 和 dllGetStaticContext()。是否获取了appContext的实例, statContext 由第一个进程设置?
- 是否创建了两个单独的 MyClass 实例,每个单独 每个进程的实例
- 或者这两个进程共享一个 MyClass 实例?
这里我的理解是静态的,全局变量不跨多进程共享,其他的都是多进程共享。
这取决于操作系统如何管理地址space。在现代(32 位)Windows 操作系统中,每个进程都有一个地址。进程之间没有共同点。
这与在 DLL 中创建对象时没有什么不同。您在不同的进程中获得不同的实例。但他们可能获得相同的虚拟地址。请记住,实例的地址仅在加载 DLL 的进程中有效。
当您为 Windows 3.x 编程时,这可能会有所不同,但我怀疑您是否这样做。
编辑 代码段是否以及如何在进程之间共享可以取决于实际O/S。在 WinCE 5.0 中,您有一个共享进程槽。如果 DLL 在 sysgen 期间作为 MODULE 定位,则代码位于对所有进程相同地址范围可见的共享槽中。您在桌面 Windows 上找不到它。
在某些 O/S 中,相同的代码部分可能位于相同的 物理地址 中,但在依赖进程的 虚拟地址中可见 =23=]。但是如果你开发一个应用程序你就不需要考虑它了。代码只是可见的一个过程。当 DLL 的加载地址已被占用时,相同的 DLL 代码可以位于不同的地址。在那种情况下,O/S 将 DLL 重新定位到一个空闲的地址范围。这需要(一点)时间并且可以通过为每个 DLL 设置不同的默认加载地址来调整。