【问题标题】:Using string pointer to send a string through windows messages使用字符串指针通过windows消息发送字符串
【发布时间】:2013-10-22 07:32:26
【问题描述】:

我试图了解指向字符串的指针是如何工作的。我有一个代码(不完全是原创的),是有人写的,这个人已经不在了,所以我需要了解这种用法​​的想法。

var
  STR: string;
  pStr: ^string;
begin
  STR := 'Hello world';
  New(pStr);
  pStr^ := STR;

  PostMessage(Handle, WM_USER+1, wParam(pStr), 0);
end;

现在我确定,消息处理程序获取消息并且指针包含可以使用的字符串,但是这些操作的“幕后”会发生什么

我试着做一个小项目。我认为,将字符串分配给 str 指针所指向的内容实际上会增加原始字符串的 refcount 并且不会复制字符串,但 refcount 仍然为 1,并且似乎确实复制了内容。

那么问题来了,发生了什么?在指针上调用New 会分配一个空字符串,对吗? 分配后,我尝试查看指针指向的字符串的引用计数/长度,像这样PChar(@pStr^[1])[-8] 但它返回废话(14),长度字节也是错误的。

另外的问题是,使用指针以这种方式通过 Windows 消息传递字符串是否安全?

【问题讨论】:

  • 这样的数据传输是安全的。但也有风险,因为如果收件人没有收到您发布的消息,或者该收件人由于某种原因没有释放分配的内存,您就会发生泄漏。
  • 使用 WM_COPYDATA 您可以将任何数据发送给任何接收者,因为它是由它制作的。无需创建其他解决方案。
  • @TLama,什么情况下收件人收不到邮件?
  • @Marcus,如果收件人不存在或在消息到达之前被销毁,例如这种技术是不安全的。您只需发布一条消息,让它漂浮在希望它到达某个地方的希望中。如果没有,你有泄漏。

标签: string delphi pointers delphi-7


【解决方案1】:

New(pStr) 在堆上分配一个string 并返回一个指向它的指针。因为string 是托管类型,所以字符串默认初始化为空字符串。由于 string 被实现为指针,因此您基本上拥有的是指向指针的指针。

您的代码非常好,只要您只将消息发布到您自己的进程。由于消息的有效负载是一个指针,它只意味着在您的进程的虚拟地址空间的上下文中。如果你想发送到不同的进程,你需要一个 IPC 机制。

很明显,在将消息从队列中拉出的代码中,您需要处理字符串。像这样的:

var
  p: ^string;
  str: string;
....
p := Pointer(wParam);
str := p^; 
Dispose(p);

您查询引用计数和长度的代码是错误的。正确的做法如下:

{$APPTYPE CONSOLE}

var
  pStr: ^string;
  p: PInteger;

begin
  New(pStr);
  pStr^ := 'Hello world';

  p := PInteger(pStr^);
  dec(p);
  Writeln(p^); // length
  dec(p);
  Writeln(p^); // ref count

  Readln;
end.

输出:

11 1

【讨论】:

  • REMARK:不应该是str := string(p^);(添加了^)吗?
  • @alz str := p^;够了
猜你喜欢
  • 2013-03-09
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多