Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi-将变量指针作为字符串传递给另一个函数_Delphi_Pointers_Stream - Fatal编程技术网

Delphi-将变量指针作为字符串传递给另一个函数

Delphi-将变量指针作为字符串传递给另一个函数,delphi,pointers,stream,Delphi,Pointers,Stream,我知道这是否可能,但我需要的是通过它的指针访问(使用和释放)TStream变量,并将字符串参数传递给另一个函数 下面是一个“不起作用”的例子,说明我正在尝试做什么: procedure TForm1.Button1Click(Sender: TObject); var Stm: TMemoryStream; begin Stm := TMemoryStream.Create; try Memo.Lines.SaveToStream(Stm); Stm.Position

我知道这是否可能,但我需要的是通过它的指针访问(使用和释放)TStream变量,并将字符串参数传递给另一个函数

下面是一个“不起作用”的例子,说明我正在尝试做什么:

procedure TForm1.Button1Click(Sender: TObject);
var
  Stm: TMemoryStream;
begin
  Stm := TMemoryStream.Create;
  try
    Memo.Lines.SaveToStream(Stm);
    Stm.Position := 0;
    Memo.Clear;
    Edit.Text := IntToStr(Integer(@Stm));
  except
    Stm.Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  PStm: ^TMemoryStream;
begin
  PStm := Pointer(StrToInt(Edit.Text));
  try
    Memo.Lines.LoadFromStream(PStm^);  // <--- Access Violation
  finally
    PStm^.Free;
  end;
end;
procedure TForm1.按钮1点击(发送方:TObject);
变量
Stm:TMemoryStream;
开始
Stm:=TMemoryStream.Create;
尝试
Memo.Lines.SaveToStream(Stm);
标准位置:=0;
备忘录.清楚;
Edit.Text:=IntToStr(整数(@Stm));
除了
Stm.Free;
终止
终止
程序TForm1.按钮2单击(发送方:TObject);
变量
PStm:^TMemoryStream;
开始
PStm:=指针(stroint(Edit.Text));
尝试

Memo.Lines.LoadFromStream(PStm^);// TStream是一种引用类型。
Stm
变量包含指向流对象实例的指针。您希望传递此指针值,而不是局部变量的地址。以下是固定代码:

procedure TForm1.Button1Click(Sender: TObject);
var
  Stm: TMemoryStream;
begin
  Stm := TMemoryStream.Create;
  try
    Memo.Lines.SaveToStream(Stm);
    Stm.Position := 0;
    Memo.Clear;
    Edit.Text := IntToStr(Integer(Stm));
  except
    Stm.Free;
    raise;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Stm: TMemoryStream;
begin
  Stm := Pointer(StrToInt(Edit.Text));
  try
    Memo.Lines.LoadFromStream(Stm);
  finally
    Stm.Free;
  end;
end;

在Button1Click完成之前,您已经释放了Stm,因此在Edit1中捕获的“指针”。在Button1Click执行时,文本已过时。如果您能解释为什么您认为您想做的事情是必要的,您会得到更好的帮助。@MartynA,只有在出现异常时,Stm才会在按钮1单击时被释放。我将在一个复杂的应用程序中使用它,使用TCP通信,相信我,如果没有必要,我不会走这条路……对不起,我误读了你的“除了”作为“最终”。但是,你到底想做什么?让我试着解释一下。。。它是一个TCP客户机-服务器应用程序。它们在(服务器和客户端)之间交换字符串和流。当需要发送流时,我首先发送一个字符串消息,告诉我下一步将发送流。此时,需要检查流是什么并生成它。但我要做的是生成流并将其指针作为字符串传递…@Paruba这是一个灾难的配方。我建议您在反模式在您的应用程序中变得过于根深蒂固之前,重新设计一下以避免这个问题。我的建议是:1)将流的生命周期从生产者(Button1)和消费者(Button2)中去掉,并赋予其更长的生命周期,使其能够跨越两者。2) 将流实例传递给生产者和消费者。3) 然后,生产者和消费者都只使用流,而不必担心它的生命周期。请注意,只有在
按钮1click
的末尾和
按钮2click
中的流分配之间的堆上没有内存分配时,这才有效,因为它依赖于不更改为的内存(恶意地)再次获得相同的流。@KenWhite,谢谢。我理解并放弃了使用这种方法:)@KenWhite,据我所知,堆分配不会导致任何问题。@KenBourassa:是的,它会。在
按钮1中单击
释放流<代码>按钮2单击
假设指针地址处的内存是
TMemoryStream
,只要堆中没有其他分配发生,该假设可能会成功。如果在两次单击之间分配了一个不同的对象实例(甚至在其他地方),则它是从堆中分配的,假设失败,转换到内存流AVs。@KenBourassa:你说得对。错过了比赛。一般来说,将内存地址(指针)作为字符串传递,然后将其转换回数值,并期望以后的内容相同,这是一个坏主意。