前一篇文章介绍了为何要共用内存管理器,有人要问可不可以在编写dll时更通用一些,可以兼顾其它编译器(如果是其它编译器的话,Delphi写的dll不能与其它语言共用内存管理器),采用一定的策略来避免在dll内创建RTL自动管理的数据类型做参数或返回值,这样其它非Delphi的开发语言也可以用了!

完全可以!

一般的策略如下:

1.在主调函数中申请一块空间

2.把这个空间的地址传送给dll

3.dll内部进行逻辑运算,得到结果后把值添到主调函数传递过来的空间上

4.主调函数获取值,根据业务规则对空间进行处理(释放等操作)

在整个工作周期中,申请的内存一直掌握在主调函数的手中,没有给dll任何管理对象的机会!

看一下下面的主调函数申请内存的模板!

在这里需要强调几点:
//.不用共用内存管理器的话,数据类型需要使用Windows标准类型,如PChar!另外在dll中返回结构体时,最好结构体内的成员为基本数据类型,不要成员又是指针,一不小心就会出错!
//.PChar是一个指针,一般在主调函数中申请空间时先申请255,并把地址传入dll,dll进行逻辑处理,处理完毕后进行返回,返回时,长度可能远远小于255,所以在返回时通过一个变参告诉主调,实际只用了N个长度,这时主调在主动清理实际使用的长度!
//.一般在程序中string与PChar都是结合使用,即返回PChar后直接给一个string,这样更方便!但string类型的特殊性(与Java的string类似),直接赋值会出现问题,故需要用Move或CopyMemory进行内存复制工作,对于为什么出现问题,我想单独写一个文章来解释!
type
TGetStr=function(Src: PChar;srcLen: Integer;Buffer: PChar;var Size: Integer):boolean;stdcall; function GetDllStr: string;
var
DllHnd: THandle;
GetStr: TGetStr;
Str,Buf: PChar;
size:integer;
begin
size:=;
DllHnd := LoadLibrary(PChar('project1.dll'));
try
if (DllHnd <> ) then
begin
@GetStr :=GetProcAddress(DllHnd, 'TestFunc');
if (@GetStr<>nil) then
begin
GetMem(Str, size);{分配}
StrPCopy(Str,'asdf');
GetMem(Buf,Size);
try
GetStr(Str,size,buf,size);
result := StrPas(buf);{返回}
finally
FreeMem(Str);{释放}
FreeMem(Buf,Size);
end;
end
else
begin
application.MessageBox(PChar('DLL加载出错,DLL可能不存在!'), PChar('错误'),
MB_ICONWARNING or MB_OK);
end;
end;
finally
FreeLibrary(DllHnd);
end;
end; //dll实现
function AddStr(Src:PChar):string;
begin
result:=Src+'/Liangpei hello!';
end;
function TestFunc(Src: PChar;srcLen: Integer;Buffer: PChar;var Size: Integer):boolean;stdcall;//函数调用协议
var
LocalString:string;
begin
result:=false;
LocalString:=AddStr(Src);//一般字符串传入dll后,均要根据某些业务做一些加工或处理,AddStr就为处理函数
if (Buffer = Nil) or (Size < srcLen) then begin
SetLastError(Byte(Buffer <> Nil) * (*ERROR_MORE_DATA, need more buffer size*) );
Size := srcLen;
Exit;
end;
CopyMemory(Buffer,PChar(LocalString),Min(Size,Length(LocalString)));
Size := srcLen;
Result := true; end; exports
TestFunc;

编写dll时的内存分配策略的更多相关文章

  1. 深入了解java虚拟机(JVM) 第七章 内存分配策略

    理解了jvm内存分配策略不仅是程序性能调优的重要知识,还能够给养成自己一种良好的代码思路,一个程序的代码差异往往都是在这里体现出来的. 一.对象优先分配到Eden区域   一般来说,新创建的对象都会直 ...

  2. jvm-垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 参考: https://my.oschina.net/hosee/blog/644085 http://www.cnblogs.com/zhguang/p/Java-JVM- ...

  3. JVM性能优化系列-(2) 垃圾收集器与内存分配策略

    2. 垃圾收集器与内存分配策略 垃圾收集(Garbage Collection, GC)是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如 ...

  4. java中内存分配策略及堆和栈的比较

    Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...

  5. Memcache 内存分配策略和性能(使用)状态检查

    前言: 一直在使用Memcache,但是对其内部的问题,如它内存是怎么样被使用的,使用一段时间后想看看一些状态怎么样?一直都不清楚,查了又忘记,现在整理出该篇文章,方便自己查阅.本文不涉及安装.操作. ...

  6. 深入理解java虚拟机(2)------垃圾收集器和内存分配策略

    GC可谓是java相较于C++语言,最大的不同点之一. 1.GC回收什么? 上一篇讲了内存的分布. 其中程序计数器栈,虚拟机栈,本地方法栈 3个区域随着线程而生,随着线程而死.这些栈的内存,可以理解为 ...

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

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

  8. GC之一--GC 的算法分析、垃圾收集器、内存分配策略介绍

    一.概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本 ...

  9. JVM学习总结四——内存分配策略

    之前几篇我们介绍了jvm的内存模型以及垃圾回收机制,而本篇我们将介绍几个JVM中对象在分配内存是应该遵循的策略.毕竟,想要去优化程序,不仅要考虑垃圾回收的过程,还要从对象内存分配的角度减少gc的代价. ...

随机推荐

  1. 【Python】多进程-4

    #练习:用event事件控制进程执行顺序,下面例子中,主进程main函数在创建了子进程之后,依然会往下执行,所以会出现主进程先打印出来的情况 import multiprocessing import ...

  2. Power BI十大视觉效果,知多少?

    Power BI十大视觉效果: 图表滑块 响应式布局 一键更改方差计算 一键排序 我们的最爱:小倍数! 瀑布图中的轴断裂 层次表(完全响应) HICHERT博士的IBCS®原生支持 分段图表 - 可视 ...

  3. make clean,make distclean与make depend的区别

    make clean仅仅是清除之前编译的可执行文件及配置文件. 而make distclean要清除所有生成的文件. Makefile 在符合GNU Makefiel惯例的Makefile中,包含了一 ...

  4. rebuild online 创建时,会话被Kill修复索引测试

    rebuild online 创建时,会话被Kill修复索引 1.0实验目的:日常运维经常create index online,但是期间被kill会导致索引再次创建失败,测试解决该问题 2.0测试流 ...

  5. 最长可重区间集 spfa费用流

    给定实直线L上的n个开区间,和一个正整数k 选取若干个区间,在保证实直线L上的任意一个点最多被选出区间覆盖k次的情况下,使得这些区间的长度和最大 先把区间按照左端点排序, 考虑到重复其实就代表着相交, ...

  6. 【集成学习】sklearn中xgboost模块的XGBClassifier函数

    # 常规参数 booster gbtree 树模型做为基分类器(默认) gbliner 线性模型做为基分类器 silent silent=0时,不输出中间过程(默认) silent=1时,输出中间过程 ...

  7. 字符串(text)格式的html代码文本转为DOM对象

    /*字符串转dom对象*/ window.strimgTurnDom = function(txt) { try //Internet Explorer { xmlDoc=new ActiveXObj ...

  8. Gym - 101002K:YATP (树分治+二分+斜率优化)

    题意:给定带点权边权的树,定义路径的花费=路径边权和e+起点点权w[s]*终点点权w[t].N<2e5,e,w<1e6: 思路:首先,需要树分治. 然后得到方程dp[i]=min{ dis ...

  9. java-Random类

    1.Random类的概述和方法使用 * A:Random类的概述 * 此类用于产生随机数 * 如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数 ...

  10. SSAS aggregation 的作用及其使用

    作用: 聚合是为了解决查询在运行时的效率低下,在数据立方体部署的时候进行聚合,实际上是对数据立方体的预处理,方便以后查询.如若在部署时未进行聚合,则在以后每次查询时实际上都会进行一次集合的操作,等待结 ...