最近使用这个方法调用数据无效,希望给同样困惑的人有些帮助吧~
查了一些资料 正好项目中要和别人一起调用我编写的DLL文件
于是在代码中写入:
#pragma data_seg("s_data") // 声明共享数据段,并命名该数据段
unsigned int guiCurrentPage = 255;
#pragma data_seg()
#pragma comment(linker,"/SECTION:s_data,RWS")
当前调用这段DLL共享数据段的是项目A的b进程
然后再创建项目B的c进程
b,c进程同时静态调用“s_data”段
b进程执行
Sleep(700);
guiCurrentPage++;
cout<<"PageNo. is "<<dec<<guiCurrentPage<<endl;
c进程执行
Sleep(500);
cout<<"PageNo. is "<<dec<<guiCurrentPage<<endl;
执行两进程
共享失败,c进程guiCurrentPage变量并没有跟随b进程变量一起改变
DLL的原理应该是:
WIN系统保证系统内存中只驻留一份DLL数据,不同进程在MMC为自己映射出的4GB(32bit)空间内将要调用的代码映射到这份唯一的空间地址上,DLL中的全局变量以不同的拷贝映射到进程自己的内存空间中,这样就实现了DLL的完全分离,进程间调用DLL完全不干扰
在使用#pragma data_seg()后,DLL在实际物理地址的内存空间中只保留了一份定义段间数据,于是就可以共享数据了。
卡了好半天,对于应该注意的语法问题包括:
1.#pragma data_seg(“section名称”) section名称必须小于8字节 否则会被截断(这个只要头、尾一致截断后也是一致的,没有什么问题)
2.变量必须初始化,否则会被编译器优化到.bss段
3.#pragma comment(linker,"/SECTION:s_data,RWS") 中的大小写问题
都做了反复的修改,均无效
注意我上面的试验方法:
A项目b进程,B项目的c进程
考虑是不是即使是同一DLL的两份不同拷贝也是不行的,
于是将两进程.exe文件和一份DLL文件拷贝到同一目录
运行
通过。
结论:两份在不同路径下的同名DLL文件不被系统认为是同一DLL文件,即使查看进程调用的DLL文件名是同一DLL文件