dll共享段中一些需要注意的问题
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共享段中一些需要注意的问题的更多相关文章
- DLL函数中内存分配及释放的问题
DLL函数中内存分配及释放的问题 最近一直在写DLL,遇到了一些比较难缠的问题,不过目前基本都解决了.主要是一些内存分配引起问题,既有大家经常遇到的现象也有特殊的 情况,这里总结一下,做为资料. 错误 ...
- C#调用其它语言(例如C++)DLL文件中函数的方法摘要
有托管和非托管的概念没仔细看,接下来记录的引用Dll文件指的是无法通过VS自动完成添加引用的情况,可以使用如下方法: 步骤一: 打开“Visual Studio Tools”的“命令提示符”工具 使用 ...
- 在DLL动态链接库中封装VCL的MDI子窗体
在DLL动态链接库中封装VCL的MDI子窗体不多说了,看代码就应该明白了,曾经我遇到的问题,现在放出来大家共享! 这里是工程文件的部分: 在DLL中封装MDI子窗体需要重写DLL入口函数,具体代码如下 ...
- C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法
使用反射(Reflect)获取dll文件中的类型并调用方法 需引用:System.Reflection; 1. 使用反射(Reflect)获取dll文件中的类型并调用方法(入门案例) static v ...
- XML序列化 判断是否是手机 字符操作普通帮助类 验证数据帮助类 IO帮助类 c# Lambda操作类封装 C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法 C# -- 文件的压缩与解压(GZipStream)
XML序列化 #region 序列化 /// <summary> /// XML序列化 /// </summary> /// <param name="ob ...
- 从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法
原文:从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法 主程序 为 Main_Test.exe 被加载的DLL 为 Load_Test.dll 此DLL 中 有一个 文件夹Re ...
- VC 使用msxml6.dll动态链接库中的函数读写XML文件
VC 使用msxml6.dll动态链接库中的函数读写XML文件 目录 1 引言 2 .dll使用方法 3 常用函数总结 4 实例应用 5 运行效果预览 6 补充说明 7 不足之处 8 更新 引言: ...
- 【NX二次开发】NX内部函数,pskernel.dll文件中的内部函数
pskernel.dll文件中的内部函数,含有部分pk函数,用法可以查看pk函数帮助: ADPAPE ADVXED APPTRA ATGETO ATTGEO BLECHK BLECRB BLECVR ...
- 加载dll过程中assembly失败
错误现象: 进行插件读取时出现错误:“尝试从一个网络位置加载程序集,在早期版本的 .NET Framework 中,这会导致对该程序集进行沙盒处理.此发行版的 .NET Framework 默认情况下 ...
随机推荐
- 3,Flask 中的模板语言 Jinja2 及 render_template 的深度用法
Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符串,用于传递到前端 S ...
- VSX-5 VSXMusic 编码听音乐
给VS写个扩展来听音乐的说法,缘来已久,这两天做了个初版,使用豆瓣FM,先发出来. 插件现在只做了VS2013的,别的版本有待下一步支持. 现在暂时只有一个Adornment(就是那个有封面的),一个 ...
- 【Text Justification】cpp
题目: Given an array of words and a length L, format the text such that each line has exactly L charac ...
- 服务过美国总统竞选的非传统投票UI [解析及DEMO]
上篇文章和大家介绍了需求情况和难点分析,大家可以看这个链接了解详细 服务过美国总统竞选的非传统投票UI =================正文开始=================== ...
- spring 笔记2:Spring MVC : Did not find handler method for 问题的解决
日志显示为: Looking up handler method for path /***Did not find handler method for [/***]No mapping found ...
- python练习1 ——菱形打印
具体请看链接: 链接 2018-09-29 12:51:45
- [转载]python 变量命名规范
原文地址:python 变量命名规范作者:loveflying python源码和其他一些书籍,命名各种个性,没有一个比较统一的命名规范.于是自己总结了一些,可供参考. 模块名: 小写字母,单词之间用 ...
- springboot08 jdbc
一.JDBC&连接池 1. jdbc介绍 JDBC(Java DataBase Connectivity ,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数 ...
- shell之dialog提示窗口
dialog 提示窗口 1.msgbox dialog --msgbox text 20 10 2.yesno dialog --title "Please answer&q ...
- C 语言 进阶
清单狂魔,只挖坑不填坑.. 前言 最近经常被询问 C 语言 相关的问题,突然便也觉得需要思考一下 C 语言的进阶了. 我用 C 语言写过的最大的一个项目,也只是那个贪吃蛇,后来就断断续续地用 Pyth ...