DLL共享数据
来源:互联网 发布:歌词编辑软件 编辑:程序博客网 时间:2024/06/06 08:48
在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的,因为所有的进程用的都收同一块地址空间;而在Win32环境中,情况却发生了变化,每个进程都有了它自己的地址空间,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。(在物理内存中,多进程载入DLL时,DLL的代码段实际上是只加载了一次,只是将物理地址映射到了各个调用它的进程的虚拟地址空间中,而全局数据会在每个进程都分别加载)。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。
因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程之间共享存储器是通过存储器映射文件技术实现的。也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
在#pragma data_seg("DLLSharedSection")和#pragma data_seg()之间的所有变量将被访问该Dll的所有进程看到和共享。仅定义一个数据段还不能达到共享数据的目的,还要告诉编译器该段的属性,有三种方法可以实现该目的(其效果是相同的),一种方法是在.DEF文件中加入如下语句:
下面是具体代码实现:
因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程之间共享存储器是通过存储器映射文件技术实现的。也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
在DLL的实现文件中添加下列代码:
#pragma data_seg("DLLSharedSection") // 声明共享数据段,并命名该数据段 int SharedData = 123; // 必须在定义的同时进行初始化!!!!#pragma data_seg()
在#pragma data_seg("DLLSharedSection")和#pragma data_seg()之间的所有变量将被访问该Dll的所有进程看到和共享。仅定义一个数据段还不能达到共享数据的目的,还要告诉编译器该段的属性,有三种方法可以实现该目的(其效果是相同的),一种方法是在.DEF文件中加入如下语句:
SETCTIONS DLLSharedSection READ WRITE SHARED
另一种方法是在项目设置的链接选项(Project Setting --〉Link)中加入如下语句:
/SECTION:DLLSharedSection,rws
还有一种就是使用指令:
#pragma comment(linker,"/section:.DLLSharedSection,rws")
那么这个数据节中的数据可以在所有DLL的实例之间共享了。所有对这些数据的操作都针对同一个实例的,而不是在每个进程的地址空间中都有一份。
当进程隐式或显式调用一个动态库里的函数时,系统都要把这个动态库映射到这个进程的虚拟地址空间里。这使得DLL成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈。
下面来谈一下在具体使用共享数据段时需要注意的一些问题:
· 所有在共享数据段中的变量,只有在数据段中经过了初始化之后,才会是进程间共享的。如果没有初始化,那么进程间访问该变量则是未定义的。
· 所有的共享变量都要放置在共享数据段中。如何定义很大的数组,那么也会导致很大的DLL。
· 不要在共享数据段中存放进程相关的信息。Win32中大多数的数据结构和值(比如HANDLE)只在特定的进程上下文中才是有效地。
· 每个进程都有它自己的地址空间。因此不要在共享数据段中共享指针,指针指向的地址在不同的地址空间中是不一样的。
· DLL在每个进程中是被映射在不同的虚拟地址空间中的,因此函数指针也是不安全的。
当然还有其它的方法来进行进程间的数据共享,比如文件内存映射等,这就涉及到通用的进程间通信了,这里就不多讲了。
下面是具体代码实现:
<span style="color:#FF0000;">//ShareDll.dll code</span>#include "stdafx.h"#include <stdio.h>#pragma data_seg("ShareSec")int globalint = 0;//把globalint放入ShareSec段#pragma data_seg()#pragma comment(linker,"/SECTION:ShareSec,RWS")//告诉编译器为ShareSec段添加共享段读写属性BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){printf("globalint = %d \n",globalint);globalint = 5; return TRUE;}
<span style="color:#FF0000;">//LoadDll.exe code</span>#include "stdafx.h"#include <windows.h>#include <string.h>#include <stdio.h>int main(int argc, char* argv[]){HANDLE m_hDll;m_hDll=LoadLibraryA(".\\ShareDLL");getchar();return 0;}
用peid看看新创建的段:
已经创建成功了,再用测试代码看看结果吧:
0 0
- DLL共享数据方法
- DLL共享数据段
- 共享DLL中的数据
- DLL 中的共享数据
- dll中共享数据
- dll共享数据
- DLL 共享数据学习
- DLL共享数据段
- DLL共享数据
- 进程共享同一个DLL数据
- DLL实现数据内存共享
- DLL内存映像共享数据
- DLL共享数据段,实现多进程数据共享总结
- DLL共享数据段,实现多进程数据共享总结
- DLL之共享数据段(转)
- 多个程序dll共享数据
- DLL在应用程序间共享数据
- 使用DLL在进程间共享数据
- Bmob文档阅读5-支付快速入门
- 关于游戏中的分享之ShareSDK的研究续一
- C++常量折叠
- POJ 2932 (扫描线)
- 我的图像处理领域收藏网站
- DLL共享数据
- store_schema.sql学习sql与plsql
- jquery获得焦点按下enter键清除文本框
- Android中Bitmap和Drawable详解
- iOS开发-基础:MD5加密算法
- mysql 连表查询结果集图解
- vagrant
- 全功能智能车之CCD液晶显示定时器触发ADC 触发DMA传输(CCD补充篇)(第十六篇)
- Python实现单隐层神经网络