1

当我尝试将 tmemorystream 作为 var 或指向过程的指针传递时,它返回已损坏。这样做的正确方法是什么?

例如:

function tform1.downloadmemupdate(url, desc: string; var data: tmemorystream; var msg: string): boolean;
begin
  filelabel.Caption:=desc;
  downloadmemthread:=tdownloadmemthread.create(url);
  dlcancelbtn.Enabled:=true;
  downloadmemthread.dlstart;
  waitforsingleobject(downloadmemthread.Handle, INFINITE);

  downloadmemthread.data.SaveToStream(data); //corrupted
  downloadmemthread.data.SaveToFile('data.zip');  //works

  dlcancelbtn.Enabled:=false;
  result:=not (downloadmemthread.canceled and downloadmemthread.success);
  dlcanceled:=downloadmemthread.canceled;
  msg:=downloadmemthread.msg;
  downloadthread.Free;
end;
4

1 回答 1

5

您不在data此方法中创建。由于它是一个 var (byref) 参数,我希望它在 内创建 tform1.downloadmemupdate,即:

data := TMemoryStream.Create;

请注意,如果您创建这样的对象,您将需要在其他地方释放它,可能在调用代码中。

例如

   Data := nil;
   try
     downloadmemupdate(url, desc, data, msg);
     // do something with data
   finally
     Data.Free;
   end;  

另一种选择(也是 Delphi 中的惯用方法)是按值传递对象(不带 var)。并将其留给调用代码来创建和销毁它们。这主要是因为 Delphi 没有垃圾收集,所以它迫使编写调用代码的人考虑“所有权”。

这将是

function tform1.downloadmemupdate(url, desc: string; data: TStream; var msg: string): boolean;
begin
  filelabel.Caption:=desc;
  downloadmemthread:=tdownloadmemthread.create(url);
  try
    ...
    downloadmemthread.data.SaveToStream(data); //corrupted
    downloadmemthread.data.SaveToFile('data.zip');  //works    
  finally
    downloadmemthread.Free;
  end;

end;

调用代码:

   Data := TMemoryStream.Create;
   try
     downloadmemupdate(url, desc, data, msg);
     // do something with data
   finally
     Data.Free;
   end;  
于 2012-11-06T05:43:11.583 回答