在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的,因为所有的进程用的都收同一块地址空间;而在Win32环境中,情况却发生了变化,每个进程都有了它自己的地址空间,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。(在物理内存中,多进程载入DLL时,DLL的代码段实际上是只加载了一次,只是将物理地址映射到了各个调用它的进程的虚拟地址空间中,而全局数据会在每个进程都分别加载)。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。
因此,在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在每个进程中是被映射在不同的虚拟地址空间中的,因此函数指针也是不安全的。

当然还有其它的方法来进行进程间的数据共享,比如文件内存映射等,这就涉及到通用的进程间通信了,这里就不多讲了。

DLL入门浅析(5)——使用DLL在进程间共享数据相关推荐

  1. VC 利用DLL共享区间在进程间共享数据及进程间广播消息

    在进程间共享数据有很多种方法,剪贴板,映射文件等都可以实现,这里介绍用 DLL 的共享区间在进程间共享数据,及共享数据有变化时及时的反馈给各相关进程. 一.在DLL中设置共享区间 在DLL中是用数据段 ...

  2. windows核心编程之进程间共享数据

    有时候我们会遇到window进程间共享数据的需求,例如说我想知道系统当前有多少某个进程的实例. 我们能够在程序中定义一个全局变量.初始化为0.每当程序启动后就加1.当然我们我们能够借助第三方介质来储存 ...

  3. python 多进程共享变量manager_python 进程间共享数据 multiprocessing 通信问题 — Manager...

    Python中进程间共享数据,处理基本的queue,pipe和value+array外,还提供了更高层次的封装.使用multiprocessing.Manager可以简单地使用这些高级接口. Mana ...

  4. python进程间共享数据_python 进程间共享数据 (二)

    Python中进程间共享数据,除了基本的queue,pipe和value+array外,还提供了更高层次的封装.使用multiprocessing.Manager可以简单地使用这些高级接口. Mana ...

  5. 如何在进程间共享数据

    1.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效的进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换,就如同 ...

  6. c++ 内存映射文件进程间共享数据

    int main(int argc, char *argv[])   {       //RecursiveDelete("C:\\20_128\\");       //Self ...

  7. 进程锁、事件、进程队列、进程间共享数据、生产者消费者模型

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 进程锁(Lock) 锁的基本概念 锁的基本用法 模拟12306抢票软件 信号量:Semaphone 概念 Semaphore ...

  8. android 共享数据,android进程间共享简单数据

    我们知道,在android中,保存简单的数据最方便的就是使用SharedPreferences,然而,SharedPreferences虽然说也可以设置成进程间共享数据,但是并不可靠(更致命的是,不同 ...

  9. linux共享内存示例,linux 进程间共享内存示例

    写入端: #include #include #include #include #include using namespace std; struct MappingDataType { int ...

最新文章

  1. 安全攻防技能——Web安全——XSS
  2. vue 目录名称详解_使用脚手架创建vue项目目录详解
  3. C# .NET Web API 如何自訂 ModelBinder
  4. css学习笔记2--多重边框
  5. linux系统命令行基础知识点
  6. Oracle配置监听要注意的地方
  7. uva 11054——Wine trading in Gergovia
  8. python集群到hadoop_如何使用Hadoop流在本地Hadoop集群中运行MRJob?
  9. jQuery表格排序总成-tablesorter
  10. 电脑键盘上每个键的作用_键盘F键有什么作用 键盘F键作用介绍【详解】
  11. Spring5+CXF整合开发REST之一次坑旅
  12. 论开心网和人人网的衰落
  13. C++内存汇编逆向安全全集
  14. js批量删除微博教程
  15. 想做合格的产品经理,你需要这个证书
  16. RMII RGMII MII GMII个人总结
  17. 绘制scara机器人工作空间
  18. ubuntu 改屏幕分辨率命令_Ubuntu修改屏幕分辨率
  19. 汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp 寄存器 含义
  20. 数据加解密之Java实现Base64加密

热门文章

  1. springboot的自动配置原理
  2. Spring Cloud Gateway介绍(二)
  3. RabbitMq链接
  4. Java语言中的注释有哪些
  5. CSS中盒模型的理解
  6. 一步一步了解Promise原理
  7. [置顶] mkdir函数-linux
  8. Veeam Backup Replication试用(三):配置备份(Backup Job)与恢复(Restore)
  9. PHP-什么是PHP?为什么用PHP?有谁在用PHP?
  10. POJ-3070 Fibonacci 快速矩阵幂