正常来说,一个可执行文件运行多个实例,这些实例不会共享可执行文件中的全局和静态变量。因为Windows通过写时复制机制来保证各个进程的全局静态区互相独立,当然DLL中的全局和静态变量也是被这样处理的。当不同的进程将DLL映射到自己的内存空间时,系统会为那些全局和静态变量创建不同的实例。那进程间共享DLL全局变量是如何实现的呢??
我们可以在DLL中使用如下语句:
#pragma data_seg("KookNut")
来创建一个段,用来存放那些需要共享的数据,要记得初始化这些数据,并且设置链接器开关,使该段在所有映射DLL的进程中成为共享读写属性:
#pragma comment(linker,"/SECTION:KookNut,RWS")//告诉编译器共享读写
当我们DLL中的这个段废除了拷贝写机制之后,我们在一定意义上也就可以实现进程间的相互通信了,对同一个数据进行共享的读写访问,当然这样的设计有安全方面的漏洞,但在这里我们只是学习一下这种通信方法。
可以自己写两个进程加载动态库之后,进行测试,下面附上DLL中的函数和共享段代码:
#include"Dll.h"
//我们创建了自己的段 并且在段中放入一些变量 必须初始化
#pragma data_seg("KookNut") //建立一个新的数据段的名字
//共享数据
我们创建了自己的段 并且在段中放入一些变量
必须初始化否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。*/
int __Count = 0;
TCHAR __SharedData[0x1000] = _T("Hello China");
#pragma data_seg() //恢复到正常段继续编程
//按照原本来说,当我们对映射出来的文件进行修改时候,会触发拷贝写机制
//段的SHARED属性是关闭了写时复制机制
#pragma comment(linker,"/SECTION:KookNut,RWS")//告诉编译器共享读写
//自己没有调用DllMain(这几个字母大小写敏感),那会在C/C++的运行库中调用它的DllMain函数
//导出函数
int GetSharedCount()
__Count++;
return __Count;
TCHAR* GetSharedData()
return __SharedData;
void SetSharedData(TCHAR* ParameterData)
memcpy(__SharedData, ParameterData, sizeof(__SharedData));
“志不强者智不达。”看到这句话,想起我的兄弟强达了,志不强者智不达,真棒!!
参考书籍:
《Windows核心编程》(第五版)