DLL共享数据段

//变量定义,不同Instance共享的该变量
#pragma data_seg("SHARED")
static HHOOK  hhk=NULL; //鼠标钩子句柄
static HINSTANCE hinst=NULL; //本dll的实例句柄 (hook.dll)
#pragma data_seg()
#pragma comment(linker, "/section:SHARED,rws")
//以上的变量共享哦!


1.#pragma data_seg()一般用于DLL中。也就是说,在DLL中定义一个共享的,有名字的数据段。
最关键的是:这个数据段中的全局变量可以被多个进程共享。否则多个进程之间无法共享DLL中的全局变量。
2.共享数据必须初始化,否则微软编译器会把没有初始化的数据放到普通的未初始化数据段中而不是放在shared中,从而导致多个进程之间的共享行为失败。


第一个#pragma叙述建立数据段,这里命名为shared。您可以将这段命名为任何一个您喜欢的名字。在这里的#pragma叙述之后的所有初始化了的变量都放在shared数据段中。
第二个#pragma叙述数据段的结束。
连结器必须知道有一个"shared"共享数据段。可以直接用DLL原始码指定连结选项,如:
#pragma comment(linker,"/SECTION:shared,RWS")        //字母RWS表示段具有读、写和共享属性


介绍:

http://baike.baidu.com/link?url=PK_XeHTkADDTAT8dsYWxHOxIBerKW9dbL5a0xPEcMWbuuNjQ57ZqZT95-i5uMqj3SKL30O4Uea5cJFohadc6aq
在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;而在Win32环境中,情况却发生了变化,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。
因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程 之间共享存储器是通过存储器映射文件技术实现的。也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些 变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
#pragma data_seg预处理指令用于设置共享数据段,例如:
#pragma data_seg("SharedDataName")
HHOOK hHook=NULL;
#pragma data_seg()
#pragma comment(linker,"/section:.SharedDataName,rws")

说明:

#pragma data_seg("SharedDataName")和#pragma data_seg()之间的所有变量将被访问该Dll的所有进程看到和共享。
#pragma comment(linker,"/section:.SharedDataName,rws")设置这个数据节中的数据可以在所有DLL的实例之间共 享。所有对这些数据的操作都针对同一个实例的,而不是在每个进程的地址空间中都有一份。
当进程隐式或显式调用一个动态库里的函数时,系统都要把这个动态库映射到这个进程的虚拟地址空间里(以下简称"地址空间")。这使得DLL成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈。


下面看一个实际应用,用共享数据来统计应用程序启动的次数,并作相应的处理:

//在应用程序的入口处:
//控制应用程序只能启动一次
#pragma data_seg("flag_data")
int count=0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:flag_data,RWS")

if(count > 1)
{
	MessageBox("已经启动了一个应用程序","Warning",MB_OK);
	return FLASE;
}
count++;


你可能感兴趣的:(#pragma,data_seg)