动态链接库(.dll)中的对象是否跨进程共享

时间:2015-03-09 16:20:57

标签: c++ dll multiprocessing dynamic-linking

假设我的.dll文件中有两个类和一个.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实例?

我的理解是静态的,全局变量不在多个流程之间共享,但其他流程在多个流程中共享。

1 个答案:

答案 0 :(得分:1)

这取决于操作系统如何管理地址空间。在现代(32位)Windows操作系统中,每个进程都有一个地址。流程之间没有任何共同之处。

在DLL中创建对象时,这没有什么不同。您在不同的进程中获得不同的实例。但他们可能会获得相同的虚拟地址。请记住,实例的地址仅在加载DLL的过程中有效。

当您为Windows 3.x编程时,这可能会有所不同,但我怀疑您是否这样做。

编辑进程之间共享代码段的方式和方式取决于实际的操作系统。在WinCE 5.0中,您有一个共享进程槽。如果在sysgen期间将DLL定位为MODULE,则代码位于此共享槽中,对于所有进程可见的相同地址范围。你在桌面Windows上找不到这个。

在某些操作系统中,相同的代码段可能位于相同的物理地址中,但在依赖于进程的虚拟地址中可见。但是如果你开发一个应用程序,你就不需要考虑它。代码只是一个进程可见。当DLL的加载地址已经被占用时,相同的DLL代码可以位于不同的地址。在这种情况下,O / S将DLL重定位到空闲的addrrss范围。这需要(一点点)时间,可以通过为每个DLL设置不同的默认加载地址来进行调整。