假设我的.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();
}
我的理解是静态的,全局变量不在多个流程之间共享,但其他流程在多个流程中共享。
答案 0 :(得分:1)
这取决于操作系统如何管理地址空间。在现代(32位)Windows操作系统中,每个进程都有一个地址。流程之间没有任何共同之处。
在DLL中创建对象时,这没有什么不同。您在不同的进程中获得不同的实例。但他们可能会获得相同的虚拟地址。请记住,实例的地址仅在加载DLL的过程中有效。
当您为Windows 3.x编程时,这可能会有所不同,但我怀疑您是否这样做。
编辑进程之间共享代码段的方式和方式取决于实际的操作系统。在WinCE 5.0中,您有一个共享进程槽。如果在sysgen期间将DLL定位为MODULE,则代码位于此共享槽中,对于所有进程可见的相同地址范围。你在桌面Windows上找不到这个。
在某些操作系统中,相同的代码段可能位于相同的物理地址中,但在依赖于进程的虚拟地址中可见。但是如果你开发一个应用程序,你就不需要考虑它。代码只是一个进程可见。当DLL的加载地址已经被占用时,相同的DLL代码可以位于不同的地址。在这种情况下,O / S将DLL重定位到空闲的addrrss范围。这需要(一点点)时间,可以通过为每个DLL设置不同的默认加载地址来进行调整。