编写dll时的内存分配策略
前一篇文章介绍了为何要共用内存管理器,有人要问可不可以在编写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时的内存分配策略的更多相关文章
- 深入了解java虚拟机(JVM) 第七章 内存分配策略
理解了jvm内存分配策略不仅是程序性能调优的重要知识,还能够给养成自己一种良好的代码思路,一个程序的代码差异往往都是在这里体现出来的. 一.对象优先分配到Eden区域 一般来说,新创建的对象都会直 ...
- jvm-垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 参考: https://my.oschina.net/hosee/blog/644085 http://www.cnblogs.com/zhguang/p/Java-JVM- ...
- JVM性能优化系列-(2) 垃圾收集器与内存分配策略
2. 垃圾收集器与内存分配策略 垃圾收集(Garbage Collection, GC)是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如 ...
- java中内存分配策略及堆和栈的比较
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- Memcache 内存分配策略和性能(使用)状态检查
前言: 一直在使用Memcache,但是对其内部的问题,如它内存是怎么样被使用的,使用一段时间后想看看一些状态怎么样?一直都不清楚,查了又忘记,现在整理出该篇文章,方便自己查阅.本文不涉及安装.操作. ...
- 深入理解java虚拟机(2)------垃圾收集器和内存分配策略
GC可谓是java相较于C++语言,最大的不同点之一. 1.GC回收什么? 上一篇讲了内存的分布. 其中程序计数器栈,虚拟机栈,本地方法栈 3个区域随着线程而生,随着线程而死.这些栈的内存,可以理解为 ...
- DLL函数中内存分配及释放的问题
DLL函数中内存分配及释放的问题 最近一直在写DLL,遇到了一些比较难缠的问题,不过目前基本都解决了.主要是一些内存分配引起问题,既有大家经常遇到的现象也有特殊的 情况,这里总结一下,做为资料. 错误 ...
- GC之一--GC 的算法分析、垃圾收集器、内存分配策略介绍
一.概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本 ...
- JVM学习总结四——内存分配策略
之前几篇我们介绍了jvm的内存模型以及垃圾回收机制,而本篇我们将介绍几个JVM中对象在分配内存是应该遵循的策略.毕竟,想要去优化程序,不仅要考虑垃圾回收的过程,还要从对象内存分配的角度减少gc的代价. ...
随机推荐
- mysql_connect和mysql_pconnect区别
php中mysql_pconnect()的实现方式:其实mysql_pconnect()本身并没有做太多的处理,它唯一做的只是在php运行结束后不主动close掉mysql的连接.mysql_pcon ...
- Spring Boot 揭秘与实战(六) 消息队列篇 - RabbitMQ
文章目录 1. 什么是 RabitMQ 2. Spring Boot 整合 RabbitMQ 3. 实战演练4. 源代码 3.1. 一个简单的实战开始 3.1.1. Configuration 3.1 ...
- ubuntu下载超快的一个站点
http://mirrors.163.com/ubuntu-releases/14.04/
- django配置Ueditor富文本编辑器
1.https://github.com/twz915/DjangoUeditor3下载包,进入包文件夹,找到DjangoUeditor包拷贝到项目下,和xadmin同级目录 2.找到项目的setti ...
- PHPweb应用攻击总结(转)
XSS跨站脚本 概念:恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的. 危害: 盗取用户COOKIE信息. 跳转 ...
- 【leetcode】58-LengthofLastWord
problem Length of Last Word 只有一个字符的情况: 最后一个word至字符串末尾之间有多个空格的情况: code1 class Solution { public: int ...
- run
和配置块不同,运行块在注入器创建之后被执行,它是所有AngularJS应用中第一个被执行的方法运行块通常用来注册全局的事件监听器.例如,我们会在.run()块中设置路由事件的监听器以及过滤未经授权的请 ...
- EasyUI 文本框回车和普通回车
easyui 回车 $('#Destination_Code').textbox('textbox').bind('keypress', function (e) { ) { } } 普通回车 < ...
- 【Wannafly挑战赛22A计数器】【裴蜀定理】
https://www.nowcoder.com/acm/contest/160/A 题目描述 有一个计数器,计数器的初始值为0,每次操作你可以把计数器的值加上a1,a2,...,an中的任意一个整数 ...
- Javascript中的 “&” 和 “|” 详解
转自:https://www.jb51.net/article/104394.htm 一.前言: 在文章开始之前,先出几个题目给大家看看: var num1 = 1 & 0; console. ...