我编了一个DLL,里面有一个自定义类。然后在里面有一个类的实例。有创建,释放函数输出。有一个TLIST的函数总是不对。
procedure TLearnInfo.ReadAllRecord(var List: TList);
var
Fp:TFileStream;
Buf:^TCumRecode;
i,Count:integer;
begin
count:=RecCount;
Fp:=TFileStream.Create(FFileName,fmOpenRead);
Fp.Seek(0,soFromBeginning);
for i:=0 to Count-1 do
begin
Fp.Seek(i*Sizeof(TCumRecode),soFromBeginning);
GetMem(buf,Sizeof(TCumRecode));
Fp.ReadBuffer(buf^,Sizeof(TCumRecode));
List.Add(Buf);
end;
Fp.Free;
end;
这个函数在DLL中。
procedure ReadAllRecord(var List:Tlist);//输出函数
begin
LearnInfo.ReadAllRecord(List);
end;
测试中,总是最后一个LIST.ITEM[*]释放时,总是出无效指针的错误。
但写在一个EXE程序中,没有任何错误,也没有内存泄露。这是为什么。我加了SHAREMM也没用,反而别的函数不能执行了。
procedure TLearnInfo.ReadAllRecord(var List: TList);
var
Fp:TFileStream;
Buf:^TCumRecode;
i,Count:integer;
begin
count:=RecCount;
Fp:=TFileStream.Create(FFileName,fmOpenRead);
Fp.Seek(0,soFromBeginning);
for i:=0 to Count-1 do
begin
Fp.Seek(i*Sizeof(TCumRecode),soFromBeginning);
GetMem(buf,Sizeof(TCumRecode));
Fp.ReadBuffer(buf^,Sizeof(TCumRecode));
List.Add(Buf);
end;
Fp.Free;
end;
这个函数在DLL中。
procedure ReadAllRecord(var List:Tlist);//输出函数
begin
LearnInfo.ReadAllRecord(List);
end;
测试中,总是最后一个LIST.ITEM[*]释放时,总是出无效指针的错误。
但写在一个EXE程序中,没有任何错误,也没有内存泄露。这是为什么。我加了SHAREMM也没用,反而别的函数不能执行了。
你可以用new函数个纪录分配指针。procedure TLearnInfo.ReadAllRecord(var List: TList);
var
Fp: TFileStream;
Buf: ^TCumRecode;
i, Count: integer;
begin
count := RecCount;
Fp: =T FileStream.Create(FFileName,fmOpenRead);
Fp.Seek(0,soFromBeginning);
for i:=0 to Count - 1 do
begin
Fp.Seek(i*Sizeof(TCumRecode),soFromBeginning);
new(Buf);
// 用文件信息填充纪录;
// 可能不能用下面的方法填充,必须先分析出来。
// 你可以先用常量填充作一些测试.
//Fp.ReadBuffer(buf^,Sizeof(TCumRecode));
List.Add(Buf);
end;
Fp.Free;
end;
试着将
procedure TLearnInfo.ReadAllRecord(var List: TList);改为
Function TLearnInfo.ReadAllRecord: TList;
然后在主程序中进行
List.Add(Buf); 吧.希望有些帮助.
我试了换参数名,无效。
注意:我出错是在EXE中释放最后一个list.items[i]中的指针出效指针的错误,前面是正常的。
急.......
“DLL和主程序一般是不共享内存区域的”如何共享呢?
var
Fp:TFileStream;
Buf:^TCumRecode;
i,count:integer;
a:TList;
begin
a:=TList.Create;
count:=RecCount;
Fp:=TFileStream.Create(FFileName,fmOpenRead);
Fp.Seek(0,soFromBeginning);
For i:=0 to Count-1 do
begin
Fp.Seek(i*SizeOf(TCumRecode),soFromBeginning);
New(buf);
Fp.ReadBuffer(buf^,SizeOf(TCumRecode));
a.Add(buf);
end;
Fp.Free;
Result:=a;
end;
更乱了,一会出无效,一会不出。
这句华肯定不对了,你怎么肯定文件中的数据流就是内存的二进制形式要分析出来的。
List.Add(Buf);
var
list:TList;
i:integer;
tmp:^TCumRecode;
begin
List:=TList.Create;
ReadAllRecord(List);//DLL中的函数
for i:=0 to list.Count-1 do
begin
tmp:=list.Items[i];
ListBox1.Items.Add(DateTimeToStr(tmp^.UseDate));
Dispose(tmp);
end;
List.Free;
end;
*********************************************
freemem(tmp, Sizeof(TCumRecode));
我做了测试,当用dispose释放内存的时候,在程序退出的时候报非法指针。
改成freemem后错误排除。
TCumRecode = record
id: integer;
name: string;
end;procedure ReadAllRecord(var List: TList);
var
Buf: ^TCumRecode;
i, Count: integer;
begin
count := 12; for i := 0 to Count-1 do
begin
GetMem(buf, Sizeof(TCumRecode));
buf.id := 2;
buf.name := 'the name is ' + inttostr(I);
List.Add(Buf);
end;
end;
1。用sysgetmem在全局对内分配内存,然后用sysfreemem释放没有错。
2。你把dispose的方法写在dll内,就是释放的时候访到dll中执行也没错。至于为什么在dll中分配内存和在exe中分配内存有什么不一样,我还没搞清楚。不过我调试的时候发现,他们申请的地址段不一样,而且间隔很大。还有就是数据结构中的string等的内存自动管理型的变量到底delphi是怎么管理的能够管理到何种程度我也不太清楚。我觉得还是用delphi推荐的pchar来表示字符串的好,能力有限呀,不过我会继续研究的。