如何实现在dll 中分配内存 和释放(实现了你要多少分有多少分 )(100分)

  • 主题发起人 主题发起人 newyj
  • 开始时间 开始时间
N

newyj

Unregistered / Unconfirmed
GUEST, unregistred user!
如何实现在dll 中分配内存 和释放
///////////dll
library PrjDll;
uses
windows, SysUtils, Classes;
{$R *.RES}
function file2char(var P:Pchar):integer
stdcall;export;
var
fm:Tfilestream;
begin
//MessageBox(0, PChar(IntToHex(Longint(p), 8)), '', MB_OK);
fm:=Tfilestream.Create('1.txt',fmopenread);
result := fm.size+1;
getMem(p,fm.size+1);
//MessageBox(0, PChar(IntToHex(Longint(p), 8)), '', MB_OK);
fm.read(p,fm.size);
fm.Free;
end;
procedure delmem(p:pchar);
begin
freemem(p);
end;
exports
file2char,
delmem;
begin
end.
//测试程序

function file2char(var P:Pchar):integer
stdcall;external 'PrjDll.DLL';
procedure delmem(p:pchar)
stdcall;external 'PrjDll.DLL';
var
Form1: TForm1;

implementation
var
p:pchar;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var

isize:integer;
begin
//getmem(p,8)
//如果分配的内存比实际需要的大没问题,小了就不行;
//我想知道dll中如何去改变内存大小;好像ReallocMem不行
//p[0]:=#0;
// MessageBox(0, PChar(IntToHex(Longint(p), 8)), '', MB_OK);

isize:=file2char(p);
// MessageBox(0, PChar(IntToHex(Longint(p), 8)), '', MB_OK);

if isize>0 then
begin
richedit1.Clear;
richedit1.Lines.add(p);
end
else richedit1.Lines.add('dfadfdas');
// freemem(p,isize);
delmem(p);
p:=nil;

end;

end.

 
呵呵, 你肯给多少分啊?

//DLL
library PrjDll;
uses
Windows, SysUtils, Classes;
{$R *.RES}

function file2char(var P: PChar): Integer
stdcall;
var
fm: Tfilestream;
L: Integer;
S: string;
begin
fm := TFilestream.Create('1.txt', fmOpenRead);
try
L := fm.SIZE + 1;
GetMem(P, L);
fm.ReadBuffer(P[0], L - 1);
Result := L;
finally
fm.Free;
end;
end;

procedure delmem(P: PChar)
stdcall;
begin
FreeMem(P);
end;

exports
file2char,
delmem;
begin
end.

//TestDLL
unit Main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

function file2char(var P: PChar): Integer
stdcall
external 'PrjDll.DLL';
procedure delmem(P: PChar)
stdcall
external 'PrjDll.DLL';

var
Form1: TForm1;

implementation
var
P: PChar;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
isize: Integer;
begin
isize := file2char(P);
if isize > 0 then
begin
Memo1.Text := P;
end
else
Memo1.Lines.Add('dfadfdas');

Delmem(P);
P := nil;
end;

end.

 
动态分配内存的函数是GetMem(),与之对应的释放函数为FreeMem()。
示例如下:
GetMem(p, sizeof(char)*8)

FreeMem(p);
你指定的内存空间太小,当然会出问题。
动态调用DLL中的函数时,就会用到函数指针,其中具体内存地址由系统自动分配。
如果你是指DLL自己的内存分配及释放,那么只要在工程文件中的begin...end部分添加初始化代码即
可。你可以利用GetProcAddress函数获取给定模块中系统分配给函数的地址即可,以后用FreeLibrary
释放占用的内存。
你必须明确一点:Windows规定DLL并不拥有它打开的任何文件或它分配的任何全局内存块。这些对象由
直接或间接调用DLL的应用程序拥有。
如果DLL非得使用全局内存,那么必须利用gmem_DDEShare属性进行分配。
Windows API函数GlobalAlloc用于从全局内存堆中分配一块指定内存,并返回该内存块的句柄。该函数
包括两个参数,第一个参数用于设置内存块的分配标志,第二个参数用于设置欲分配的字节数。分配的
字节数必须是32的倍数。由于用gmem_DDEShare分配的内存在分配内存的模块终止时自动抛弃,因而不必
调用GlobalFree显式释放内存。
示例如下:在初始化代码中分配DLL全局内存 
begin
DLLMem := GlobalAlloc(gmem_MOVEABLE and gmem_DDEShare,num);
if DLLMem = 0 then
MessageDlg('不能分配内存空间',mtWarning,[mbOK],0);
end.
num是一个预定义的常数。gmem_Moveable指分配可移动的内存,gmem_DDEShare 分配可由应用程序共享
的内存。当然还有其他一些分配标志,你查看一下相关资料即可。
Good Luck !!!
 
我的错误就是
procedure delmem(p:pchar)
忘了加stdcall
 
[?]给你500分如何 ;[?]我怎样给贴子加分到500?
 
贴出来了就不能修改分的了。 
更好啊,替你省了一笔。 [:D]
 
csdn到是能加分!
 

Similar threads

后退
顶部