windows DLL共享变量

在Windows中同一个dll或者可执行文件的多个实例之间的全局静态变量是独立的(Linux中动态链接库可以共享全局变量的),不存在共享全局或者静态变量,这样的设计是为了安全考虑,但是有时候在dll见共享变量也会带来很多方便。最近在项目中编写log收集模块,使用的是第三方库log4cplus,项目有两个进程,希望两个进程的log都写到一个文件,所以想在两个进程之间共享一个log instance,但是windows却没有提供直接共享静态变量的机制,所以就另寻他法。windows其实提供了一种共享的方式。

我们知道一个dll或者exe文件映像是由很多段组成的,常见的有.text段用来存放代码,.bss段存放那些没有被初始化的数据,.data段用来存放那些已经初始化的数据,当然还有其他一些段。VS里有个Dumpbin工具可以查看各个段的基本信息。除了这些标准段外,windows允许我们创建自己的段,在编译的时候使用#pragma data_seg的方式可以创建自己的段。

#pragma data_seg("Shared")

int sharedobject = 0;

#pragma data_seg()

上面三行就是完整的在代码中添加段的过程,首先#pragma data_seg()两种用途,一个是告诉编译器新增加的段的名字,另外一个就是告诉编译编译器新增加的段的结束位置,这两个之间的已初始化变量的将被写到新增加的段中。需要非常注意的一点是编译器只会把已经显式初始化的全局变量放到Shared段中,如果没有初始化编译器会将该变量放到shared段以外的其他段中。

Microsoft Visual C++编译器提供了一个allocate声明符,允许我们将未经初始化的变量放到任何我们想要的段。

__declspec(allocate("Shared")) int shared;

那么要达到共享变量的目的,仅告诉编译器把变量放到单独的段中是不够的,还需要在链接的时候告诉链接器共享这些变量,有两种方式,一种是直接在链接命令行中添加/SECTION开关来实现,这里我们可以用/SECTION:Shared, RWS,注意后面的那个RWS是用来告诉链接器这个区域是的属性。另外一种通知编译器的方法是#pragma comment(linker, "/SECTION:Shared,RWS").

但是有一点非常重要,使用自己添加段的方式共享变量并不是一种安全的方式,会导致一些潜在的安全漏洞,所以我最后还是选择了共享内存的方式传输这些需要的数据~~

你可能感兴趣的:(windows DLL共享变量)