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

Is Object in dynamic link library(.dll) shared across process

本文关键字:是否 进程 共享 对象 dll 动态链接库      更新时间:2023-10-16

假设我的.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 的实例,由第一个进程设置的统计上下文
  • 是否创建了两个单独的 MyClass 实例,每个实例都是单独的每个进程的实例
  • 或者这两个进程共享一个 MyClass 实例?

我在这里的理解是静态的,全局变量不是在多个进程中共享的,而是在多个进程中共享的。

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

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

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

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

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