Visual C++

如何与应用程序或其他 DLL 共享自己 DLL 中的数据?

Win32 DLL 映射到调用进程的地址空间中。默认情况下,每个使用 DLL 的进程都有自己的所有 DLL 全局变量和静态变量的实例。如果 DLL 需要与它的由其他应用程序加载的其他实例共享数据,则可使用下列方法之一:

使用 data_seg 杂注创建命名数据节。

使用内存映射文件。请参见有关内存映射文件的 Win32 文档。

以下是一个使用 data_seg 杂注的示例:

复制代码

#pragma data_seg (".myseg")

int i = 0;

char a[32]n = "hello world";

#pragma data_seg()

data_seg 可用于创建新的命名节(在此示例中为 .myseg)。为清楚起见,最典型的用法是调用数据段 .shared。然后必须在 .def 文件中或者使用链接器选项 /SECTION:.MYSEC,RWS 为这个新的命名数据节指定正确的共享属性。

在使用共享数据段之前要考虑下列限制:

必须静态初始化共享数据段中的所有变量。在上面的示例中,i 初始化为 0,而 a 是初始化为“hello world”的 32 个字符。

所有共享变量放在编译 DLL 的指定数据段中。很大的数组可产生很大的 DLL。对于所有已初始化的全局变量都是如此。

永远不要将特定于进程的信息存储在共享数据段中。大多数 Win32 数据结构或值(如 HANDLE)仅在单个进程的上下文内才真正有效。

每个进程都将获取它自己的地址空间。永远不要将指针存储在共享数据段包含的变量中,这一点很重要。指针可能在某个应用程序中完全有效,但在另一个应用程序中却无效。

DLL 本身有可能加载到每个进程的虚拟地址空间中的不同地址。具有指向 DLL 中的函数或指向其他共享变量的指针是不安全的。

请注意,上述最后三点适用于内存映射文件和共享数据段。

内存映射文件优于共享数据节,原因是内存映射文件的起始位置是已知的。开发人员通过使用距离位于共享内存内的所有数据中的“共享内存节的起始位置的偏移量”,可以实现类似于指针的行为。为使此操作快速简便,强烈建议使用 __based 指针。但一定要记住:在每个进程中,基(或内存映射文件的起始位置)可能不同,因此存储 __based 指针的基的变量自身不能位于共享内存中。

这些限制对 C++ 类有重要的含义。

具有虚函数的类总是包含函数指针。具有虚函数的类永远不应存储在共享数据段中,也不应存储在内存映射文件中。这对于 MFC 类或从 MFC 继承的类尤其重要。

静态数据成员以全局变量的等效形式实现。这意味着每个进程都具有它自己的该类静态数据成员的副本。不应共享具有静态数据成员的类。

对于 C++ 类,共享数据段的初始化要求引起一个特定问题。如果共享数据段中有类似 CTest Counter(0); 的内容,则当每个进程加载 DLL 时,Counter 对象将在该进程中初始化,从而有可能每次都将对象的数据清零。这与内部数据类型(由链接器在创建 DLL 时初始化)非常不同。

由于存在这些限制,Microsoft 不建议在进程之间共享 C++ 对象。一般情况下,如果希望使用 C++ 在进程之间共享数据,请编写在内部使用内存映射文件来共享数据的类,但不要共享类实例本身。在开发这样的类时,可能需要特别小心,但它使应用程序开发人员能够完全控制共享数据的副作用。

有关创建命名数据节的更多信息,请参见位于 http://support.microsoft.com/default.aspx?ln=zh-cn 上的下列知识库文章:

“How to Share Data Between Different Mappings of a DLL”(如何在 DLL 的不同映射之间共享数据)。

“Specifying Shared and Nonshared Data in a DLL”(指定 DLL 中的共享数据和非共享数据)(Q100634)。

“Sharing All Data in a DLL”(共享 DLL 中的所有数据)。

“Memory in Shared Code Sections Is Not Shared Across Terminal Server Sessions”(共享代码节中的内存不在终端服务器会话间共享)

dll共享段中一些需要注意的问题的更多相关文章

  1. DLL函数中内存分配及释放的问题

    DLL函数中内存分配及释放的问题 最近一直在写DLL,遇到了一些比较难缠的问题,不过目前基本都解决了.主要是一些内存分配引起问题,既有大家经常遇到的现象也有特殊的 情况,这里总结一下,做为资料. 错误 ...

  2. C#调用其它语言(例如C++)DLL文件中函数的方法摘要

    有托管和非托管的概念没仔细看,接下来记录的引用Dll文件指的是无法通过VS自动完成添加引用的情况,可以使用如下方法: 步骤一: 打开“Visual Studio Tools”的“命令提示符”工具 使用 ...

  3. 在DLL动态链接库中封装VCL的MDI子窗体

    在DLL动态链接库中封装VCL的MDI子窗体不多说了,看代码就应该明白了,曾经我遇到的问题,现在放出来大家共享! 这里是工程文件的部分: 在DLL中封装MDI子窗体需要重写DLL入口函数,具体代码如下 ...

  4. C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法

    使用反射(Reflect)获取dll文件中的类型并调用方法 需引用:System.Reflection; 1. 使用反射(Reflect)获取dll文件中的类型并调用方法(入门案例) static v ...

  5. XML序列化 判断是否是手机 字符操作普通帮助类 验证数据帮助类 IO帮助类 c# Lambda操作类封装 C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法 C# -- 文件的压缩与解压(GZipStream)

    XML序列化   #region 序列化 /// <summary> /// XML序列化 /// </summary> /// <param name="ob ...

  6. 从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法

    原文:从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法 主程序 为 Main_Test.exe 被加载的DLL 为 Load_Test.dll  此DLL 中 有一个 文件夹Re ...

  7. VC 使用msxml6.dll动态链接库中的函数读写XML文件

    VC 使用msxml6.dll动态链接库中的函数读写XML文件 目录 1 引言 2 .dll使用方法 3 常用函数总结 4 实例应用 5 运行效果预览 6 补充说明 7 不足之处 8 更新   引言: ...

  8. 【NX二次开发】NX内部函数,pskernel.dll文件中的内部函数

    pskernel.dll文件中的内部函数,含有部分pk函数,用法可以查看pk函数帮助: ADPAPE ADVXED APPTRA ATGETO ATTGEO BLECHK BLECRB BLECVR ...

  9. 加载dll过程中assembly失败

    错误现象: 进行插件读取时出现错误:“尝试从一个网络位置加载程序集,在早期版本的 .NET Framework 中,这会导致对该程序集进行沙盒处理.此发行版的 .NET Framework 默认情况下 ...

随机推荐

  1. 1,MongoDB简介和安装

    一.初识MongoDB MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数 ...

  2. 1,VMware与Centos系统安装

    选择性 pc可以选择 -纯系统 Linux/windows -双系统 Windows+Linux -虚拟化技术 Windows+vmware workstation 服务器 -物理机纯系统 -物理机+ ...

  3. CSAcademy Palindromic Concatenation 字符串哈希

    题意: 题目链接 给出\(n\)个字符串,求有多少对\((i,j),i \neq j\)使得\(s_i\)与\(s_j\)拼起来是回文串 分析: 设\(s_i,s_j\)的长度分别为\(L_i, L_ ...

  4. 《数据结构与算法分析:C语言描述》复习——第八章“并查集”——并查集

    2014.06.18 14:16 简介: “并查集”,英文名为“union-find set”,从名字就能看出来它支持合并与查找功能.另外还有一个名字叫“disjoint set”,中文名叫不相交集合 ...

  5. 不作伪分享者决定完整分享我自学Python3的全部过程细节

    不作伪分享者决定完整分享我自学Python3的全部过程细节   我不要作伪分享者 十六年前我第一次见到了电脑,并深深地爱上了它: 十二年前我第一次连上了网络,并紧紧地被它爱上. 十年前的网络是田园美景 ...

  6. google protobuf 中的proto文件编写规则

    1. 简单介绍 protobuf文件:就是定义你要的消息(类似Java中的类)和消息中的各个字段及其数据类型(类似java类中的成员变量和他的数据类型) 2. Protobuf消息定义 消息由至少一个 ...

  7. Axios & fetch api & Promise & POST

    Axios & fetch api & Promise & POST https://github.com/axios/axios https://appdividend.co ...

  8. 【bzoj2770】YY的Treap 权值线段树

    题目描述 志向远大的YY小朋友在学完快速排序之后决定学习平衡树,左思右想再加上SY的教唆,YY决定学习Treap.友爱教教父SY如砍瓜切菜般教会了YY小朋友Treap(一种平衡树,通过对每个节点随机分 ...

  9. hdu 1811 Rank of Tetris (拓扑 & 并查集)

    Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  10. [SQL Server]关于标识列,标识从1开始计数的的方法

    DBCC CHECKIDENT ('表名',  RESEED, 0) //从30开始 DBCC  CHECKIDENT  (jobs,  RESEED,  30)