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

这里我的理解是静态的,全局变量不跨多进程共享,其他的都是多进程共享。

这取决于操作系统如何管理地址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 设置不同的默认加载地址来调整。