我们知道同DLL可以同时被多个进程同时载入,但其会被系统分别映射到每个进程的内存空间中,当我们需要在分处在不同进程内的DLL内创建一个可以互相操作的变量,在DLL内,一般的变量定义已经不能满足要求了,即使是全局变量也不行,虽然变量名是同一个,但在内存中,每一个进程内都有其一份拷贝,要想实现这一功能就要用到下面的方法:

#pragma data_seg("MySection")   //MySection是自定义的名字,前后要一致。
//注意,这里就是变量定义区,该区内容被上一句和下两句所包围
#pragma data_setg()
#pargma comment(Linker,"/SECTION:MySection,RWS")

 

    在DLL内用如上的方法定义的全局变量,一定是要被初始化的,否则无效。如下:

#pragma data_seg("MySection")
long nLength = 0;
#pragma data_seg()
#pargma comment(Linker,"/SECTION:MySection,RWS")

    使用#pragma data_seg的目的是告诉编译器开设一个节区(Section,这和PE文件的格式有关,如不懂可查阅相关资料),把#pragma data_seg("MySection")和#pragma data_set()之间所有被初始化的变量放在这个节区内,未被初化的变量即便定义在其中,在编译的时候也会放在其它的节区中,#pargma comment(Linker,"/SECTION:MySection,RWS")是告诉编译器,把刚刚创建的节区设置成R(可读)W(可写)S(共享)属性。

    经过这样的定义后,nLength就可以在不同的进程内共享同一份数据了,比如在A进程内通过DLL将其设置为10,那么此时在B进程内访问到的值也会是10.


Dll中共享数据的限制

  1、必须初始化共享数据段中的所有变量。
  2、所有共享变量都存放在编译DLL的指定数据段中。

  3、永远不要将特定于进程的信息存储在共享数据段中。
  4、永远不要将指针存储在共享段包含的变量中。
  5、具有虚拟函数的类总是包含函数指针。因此有虚拟函数的类永远不要存储在共享数据段中。
  6、静态数据成员以全局变量的等效形式实现。因此每个进程都有他自己的该静态数据成员的副本。不应存储具有静态数据成员的类。
  7、对于 C++ 类,共享数据段的初始化要求引起一个特定问题。如果共享数据段中有类似 CTest Counter(0); 的内容,则当每个进程加载 DLL 时,Counter 对象将在该进程中初始化,从而有可能每次都将对象的数据清零。这与内部数据类型(由链接器在创建 DLL 时初始化)非常不同。 因此不建议在进程间共享C++对象。