That is wrong. Your original call was correct. It is your Move() call inside of TargetMethod() that was wrong to begin with. It needs to be this instead:
Move(Events[0], p^^, TotalSize);
Inside of TargetMethod():
- p is a pointer to Main's Data variable.
- p^ refers to the Data variable itself.
- p^^ refers to the memory block that the Data variable is pointing at.
The 2nd parameter of Move() takes a var reference to the memory it will write to. So it needs a reference to the memory block that the Data variable is pointing at, but you are giving it a reference to the Data variable itself. Thus, this call to Move() writes to the call stack of Main(), corrupting it. That is why the 2nd call to Move() inside of Main() crashes when it tries to read from the memory pointed at by the Data variable which resides in the now-corrupted call stack. You likely overwrote the Data variable during the 1st Move.
Imagine how your Main() would need to use its Data and DataSize variables if it didn't have to pass them to TargetMethod() at all:
procedure Main;
var
Data: Pointer;
DataSize: Integer;
ByteArray: TBytes;
TotalBytes: Integer;
begin
...
GetMem(Data, ...); // <-- No ^ here
Move(..., Data^, ...); // <-- 1 ^ here
DataSize := ...; // <-- No ^ here
...
if (Data <> nil) and (DataSize > 0) then
try
TotalBytes := DataSize;
SetLength(ByteArray, TotalBytes);
Move(Data^, ByteArray[0], TotalBytes); // <-- 1 ^ here
finally
FreeMem(Data);
end;
...
end;
Now, because you added @ to Data and DataSize when passing them to TargetMethod(), you need an extra ^ on all accesses to Data and DataSize inside of TargetMethod():
GetMem(p^, TotalSize); // <-- 1 ^ here
Move(..., p^^, ...); // <-- 2 ^ here
len^ := ...; // <-- 1 ^ here