DLL何时需共享内存管理器
Delphi创建DLL时,IDE自动生成的文档中写得很清楚,当在DLL中以动态数组或String做为参数或返回值时(即RTL自动维护的数据类型),请在每个工程文件的第一个单元加上ShareMem。这样就可以使宿主程序与DLL共享内存管理器了!
这样的话,在发布程序时需要把borlndmm.DLL一同发布!
问题1:
为何要加到工程文件的第一个单元?
对于DLL和主程序这样的程序结构来说,使用2个内存管理器,在返回的数据类型为string的话,仅仅在主程序中将内存管理器中将引用数加1,而DLL的引用数不变,这样当退出DLL过程中,由于引用数为0,要对返回值进行释放,由于主程序中的数据为一个地址,将DLL地址释放,主程序中必然发生AV错误!
至于为什么ShareMem必须放第一个单元,那是因为Delphi的单元文件的initialization
的执行顺序,与dpr中引用这个单元的顺序有关;dpr中某单元引用越靠前,则某单元的initialization就越先执行!而我们程序的 内存管理器的"替换"过程就是在initialization块里实现的 看看Delphi的ShareMem里的一点代码就了解了!
问题2:
为何要把borlndmm.dll一同发布?
请参见ShareMem.pas源码!
procedure InitMemoryManager;
var
SharedMemoryManager: TMemoryManager;
MM: Integer;
begin
// force a static reference to borlndmm.dll, so we don't have to LoadLibrary
SharedMemoryManager.GetMem := SysGetMem; MM := GetModuleHandle(DelphiMM);
{$IFDEF GLOBALALLOC}
SharedMemoryManager.GetMem := xSysGetMem;
SharedMemoryManager.FreeMem := xSysFreeMem;
SharedMemoryManager.ReallocMem := xSysReallocMem;
{$ELSE}
SharedMemoryManager.GetMem := GetProcAddress(MM,'@Borlndmm@SysGetMem$qqri');//动态调用borlndmm中的GetMem函数来使主调与dll内存管理器共享
SharedMemoryManager.FreeMem := GetProcAddress(MM,'@Borlndmm@SysFreeMem$qqrpv');
SharedMemoryManager.ReallocMem := GetProcAddress(MM, '@Borlndmm@SysReallocMem$qqrpvi');
{$ENDIF}
SetMemoryManager(SharedMemoryManager);
end; initialization
if not IsMemoryManagerSet then
InitMemoryManager;//!!!!
最后建议大家使用FastMM, borlndmm.dll已经成为一般过去式了~
DLL何时需共享内存管理器的更多相关文章
- TaskTracker节点上的内存管理器
Hadoop平台的最大优势就是充分地利用了廉价的PC机,这也就使得集群中的工作节点存在一个重要的问题——节点所在的PC机内存资源有限(这里所说的工作节点指的是TaskTracker节点),执行任务时常 ...
- STL内存管理器的分配策略
STL提供了很多泛型容器,如vector,list和map.程序员在使用这些容器时只需关心何时往容器内塞对象,而不用关心如何管理内存,需要用多少内存,这些STL容器极大地方便了C++程序的编写.例如可 ...
- PHP V5.2 中的新增功能,第 1 部分: 使用新的内存管理器
PHP V5.2:开始 2006 年 11 月发布了 PHP V5.2,它包括许多新增功能和错误修正.它废止了 5.1 版并被推荐给所有 PHP V5 用户进行升级.我最喜欢的实验室环境 —— Win ...
- C/C++内存管理器
C标准库提供了malloc,free,calloc,realloc,C++标准库还提供了new, new[], delete, delete[].这些用来管理内存,看起来够用了,为啥还要自己写一个内存 ...
- BBS项目详解(forms快速创建登陆页面,登陆验证、通过阅读器进行头像上传的预览、内存管理器)
BBS项目涉及的知识点 django中知识点 钩子函数(局部钩子和全局钩子) 1.局部钩子就是用来做合法性校验,比如用户名有没有被使用等 2.全局的就是用来做对比校验,比如两次输入的密码是否一致 3. ...
- spark内存管理器--MemoryManager源码解析
MemoryManager内存管理器 内存管理器可以说是spark内核中最重要的基础模块之一,shuffle时的排序,rdd缓存,展开内存,广播变量,Task运行结果的存储等等,凡是需要使用内存的地方 ...
- Netty内存管理器ByteBufAllocator及内存分配
ByteBufAllocator 内存管理器: Netty 中内存分配有一个最顶层的抽象就是ByteBufAllocator,负责分配所有ByteBuf 类型的内存.功能其实不是很多,主要有以下几个重 ...
- android的低内存管理器【转】
本文转载自:http://blog.csdn.net/haitaoliang/article/details/22092321 版权声明:本文为博主原创文章,未经博主允许不得转载. 安卓应用不用太在意 ...
- LevelDB(v1.3) 源码阅读之 Arena(内存管理器)
LevelDB(v1.3) 源码阅读系列使用 LevelDB v1.3 版本的代码,可以通过如下方式下载并切换到 v1.3 版本的代码: $ git clone https://github.com/ ...
随机推荐
- 【Think in java读书笔记】序列化
Java的对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并能够在以后将这个字节序列完全恢复成为原来的对象. 序列化机制能自动弥补不同操作系统之间的差异,也就是说在Wind ...
- v$、v_$、gv$之间的关系
本次实验测试,oracle数据库视图中v$,v_$,gv$之间的关系 总结: v_$是动态性能视图,通过sql查询数据库基表返回记录.例如,v_$database对象是视图类型,可对其它用户授权访问: ...
- post-image.sh hacking
#********************************************************************************* #* post-image.sh ...
- 【重要】NOI-1.2-10-字符串大小
10:Hello, World!的大小 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 还记得在上一章里,我们曾经输出过的“Hello, World!”吗? ...
- 【转】【计算机视觉】opencv靶标相机姿态解算2 根据四个特征点估计相机姿态 及 实时位姿估计与三维重建相机姿态
https://blog.csdn.net/kyjl888/article/details/71305149
- 1px的实现方法
1.用伪元素实现 .border_1px_top{ position:relative;} .border_1px_top:before{ content: ""; positio ...
- strchr与sscanf
strchr(s,',')返回字符串s中从左往右第一个字符's'的指针: sscanf(输入的字符或字符串,“%格式符”,存储值):
- UE4 C++ Tips
篇写的是关于UE4的C++方面的小技巧: 1.在构造函数里 //构建组件 RootComponent = CreateDefaultSubobject<USceneComponent>(T ...
- django ---forms组件
forms组件 本文目录 1 校验字段功能 2 渲染标签功能 3 渲染错误信息功能 4 组件的参数配置 5 局部钩子 6 全局钩子 回到目录 1 校验字段功能 针对一个实例:注册用户讲解. 模型:mo ...
- day11hadoop高可用和Hive
PS:视频一直就是在演示 高可用(比较偏运维一点) PS:Active是对外提供服务的,standBy是从属备用的:但是他们是怎样保证同步的数据的呢?一个运行中zookeeper上的第三方那个工具 ...