Delphi – Using string pointer to send a string through windows messages


I am trying to understand how are pointers to strings working. I have a code (not exactly original), which was written by somebody, and the person is not around here anymore, so I need to understand the idea of such usage.

  STR: string;
  pStr: ^string;
  STR := 'Hello world';
  pStr^ := STR;

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

Now I know for sure, that a message handler gets the message and the pointer contains the string, which can be worked with, but what happens 'under the hood' of those operations ?

I tried to make a small project. I thought, that assigning string to what a str pointer is pointing to would actually increase refcount of the original string and not make any copies of a string, but refcount remained 1 and it seems it did copy the contents.

So get the question, what happened? Calling New on a pointer allocates an empty string, right?
After assignment I tried to look at refcount/length of a string the pointer pointed to like this PChar(@pStr^[1])[-8] but it returned nonsense (14), and the length byte was also wrong.

Additionally the questioin is, is it safe using pointers in such a way to pass on the string through windows messaging?

Best Solution

New(pStr) allocates a string on the heap and returns a pointer to it. Because string is a managed type, the string is default initialized, to the empty string. Since a string is implemented as a pointer, what you fundamentally have is a pointer to a pointer.

You code is perfectly fine, so long as you only post the message to your own process. Since the payload of the message is a pointer, it only means something in the context of the virtual address space of your process. If you wanted to send to a different process you'd need an IPC mechanism.

Clearly in the code that pulls the message off the queue you need to dispose of the string. Something like this:

  p: ^string;
  str: string;
p := Pointer(wParam);
str := p^; 

Your code to query the reference count and the length is just wrong. Here's how to do it correctly:


  pStr: ^string;
  p: PInteger;

  pStr^ := 'Hello world';

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



Related Question