DLL入门浅析(5)——使用DLL在进程间共享数据
转载自:http://www.cppblog.com/suiaiguo/archive/2009/07/21/90734.html
在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的,因为所有的进程用的都收同一块地址空间;而在Win32环境中,情况却发生了变化,每个进程都有了它自己的地址空间,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。(在物理内存中,多进程载入DLL时,DLL的代码段实际上是只加载了一次,只是将物理地址映射到了各个调用它的进程的虚拟地址空间中,而全局数据会在每个进程都分别加载)。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。 因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程之间共享存储器是通过存储器映射文件技术实现的。也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
在DLL的实现文件中添加下列代码:
#pragma data_seg("DLLSharedSection") // 声明共享数据段,并命名该数据段
int SharedData = ; // 必须在定义的同时进行初始化!!!!
#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在每个进程中是被映射在不同的虚拟地址空间中的,因此函数指针也是不安全的。
当然还有其它的方法来进行进程间的数据共享,比如文件内存映射等,这就涉及到通用的进程间通信了,这里就不多讲了。
DLL入门浅析(5)——使用DLL在进程间共享数据的更多相关文章
- 【转】VC 利用DLL共享区间在进程间共享数据及进程间广播消息
1.http://blog.csdn.net/morewindows/article/details/6702342 在进程间共享数据有很多种方法,剪贴板,映射文件等都可以实现,这里介绍用DLL的共享 ...
- 使用DLL在进程间共享数据
0x01 DLL在进程间共享数据理论 1.可以在Dll中使用#pragma data_seg建立共享类型的数据段将需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享,从而实现不 ...
- 【C++】DLL内共享数据区在进程间共享数据(重要)
因项目需要,需要在DLL中共享数据,即DLL中某一变量只执行一次,在运行DLL中其他函数时该变量值不改变:刚开始想法理解错误,搜到了DLL进程间共享数据段,后面发现直接在DLL中定义全局变量就行,当时 ...
- python 进程间共享数据 (二)
Python中进程间共享数据,除了基本的queue,pipe和value+array外,还提供了更高层次的封装.使用multiprocessing.Manager可以简单地使用这些高级接口. Mana ...
- 使用 WM_COPYDATA 在进程间共享数据
开发中有时需要进程间传递数据,比如对于只允许单实例运行的程序,当已有实例运行时,再次打开程序,可能需要向当前运行的实例传递信息进行特殊处理.对于传递少量数据的情况,最简单的就是用SendMessage ...
- 进程间共享数据Manager
一.前言 进程间的通信Queue()和Pipe(),可以实现进程间的数据传递.但是要使python进程间共享数据,我们就要使用multiprocessing.Manager. Manager()返回的 ...
- windows核心编程之进程间共享数据
有时候我们会遇到window进程间共享数据的需求,例如说我想知道系统当前有多少某个进程的实例. 我们能够在程序中定义一个全局变量.初始化为0.每当程序启动后就加1.当然我们我们能够借助第三方介质来储存 ...
- Python multiprocessing.Manager介绍和实例(进程间共享数据)
Python中进程间共享数据,处理基本的queue,pipe和value+array外,还提供了更高层次的封装.使用multiprocessing.Manager可以简单地使用这些高级接口. Mana ...
- Swoole 中使用 Table 内存表实现进程间共享数据
背景 在多进程模式下进程之间的内存是相互隔离的,在一个工作进程中的全局变量和超全局变量,在另一个工作进程中是无法读取和操作的. 如果只有一个工作进程,则不存在进程隔离问题,可以使用全局变量和超全局变量 ...
随机推荐
- Log4j使用教程 (转载http://www.codeceo.com/article/log4j-usage.html)
日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录.在apache网站:jakarta.apache.org/log4j 可以免费下载到Log ...
- Java中Long与long的区别(转)
Java中Long与long的区别(转) [本文转载自:http://www.cnblogs.com/bluestorm/archive/2012/04/22/2464739.html] 转载请联系原 ...
- android之旅——开始
1.文件的读取 io流读取文件,并且显示 package com.helloword; import java.io.BufferedReader; import java.io.File; impo ...
- 请输出in.txt文件中的2 4 6 8 9 10 12行
in.txt文件: 学号 姓名 性别 年龄 1001 张三 男 18 1002 赵四 男 19 1003 李丽 女 18 1004 刘芳 女 32 1005 王五 男 54 1006 小明 男 32 ...
- ADO.NET和ORACLE操作数据库传参数赋值的方式
在使用.Net使用OracleParameter进行Oracle数据库操作的时候,因为Oracle和SQLServer针对查询参数化的语法不同, 在操作SQLServer的时候使用的是@Paramet ...
- bootstrap datetimepicker 时间段选择限制
<!DOCTYPE html> <html> <head> <title></title> <link href="./bo ...
- FckEditor组件的使用(新闻浏览发布页面)
FckEditor组件的使用 准备工作: 1)将FckEditor目录拷贝到网站根目录内. 2)在Web.config的AppSetting分支中添加如下的代码,并修改FckEditor的目录和上传文 ...
- retrofit2 使用教程 及 Android 网络架构搭建 (原创)
squareup 推出 retrofit2 已经有一段时间了,现在的版本比较稳定,没有什么大坑了.网络上的教程要么太简单,只是个Demo:要么有些落时,要么复用性比较差,所以自己写个教程,供大家参考. ...
- 数据库连接未关闭,conn与rs未关闭
场景: 2000多人使用系统,早上打卡签到,时间点比较集中. 程序:会创建connction连接.但是未关闭,导致tomcat挂了.导致连接池已满 解决:conn.close,rs.close.记住一 ...
- Foudation框架之一些常用结构体和常用类
表示范围作用的结构体:NSRange: 有三种方式创建新的NSRange: 1.NSRange range: range.location = 17; ...