당신 말이 맞아. 주소는 단일 프로세스 내에서만 의미가 있습니다. 첫 번째 프로세스에서 작성하는 PMyRec 값은 대상 프로세스의 가비지 주소입니다.
창 메시지를 통해 임의의 메모리 블록을 다른 프로세스로 보내려면 wm_CopyData
메시지를 사용해야합니다. 해당 메시지에 데이터 및 크기의 주소를 지정하고 OS는 대상 프로세스의 주소 공간에 해당 메시지를 복사합니다.
데이터에 내부적으로 다른 포인터로 표시되는 문자열이 포함되어 있으므로 레코드의 12 바이트 만 복사하는 것으로 충분하지 않습니다. 하나의 메모리 블록에 레코드와 문자열 데이터를 저장하기 위해 추가 메모리를 할당해야하므로 wm_CopyData
이 복사 할 수 있으며 대상 프로세스가 읽을 수 있습니다.
스트림을 사용하여 데이터를 단일 메모리 블록으로 수집하는 방법 중 하나가 있습니다.
procedure SendRecord(Source, Target: HWnd; const Rec: TMyRec);
var
Buffer: TMemoryStream;
Len: Integer;
CopyData: TCopyDataStruct;
begin
Buffer := TMemoryStream.Create;
try
Len := Length(Rec.name);
Buffer.Write(Len, SizeOf(Len));
if Len > 0 then
Buffer.Write(Rec.name[1], Len * SizeOf(Char));
Len := Length(Rec.add);
Buffer.Write(Len, SizeOf(Len));
if Len > 0 then
Buffer.Write(Rec.add[1], Len * SizeOf(Char));
Buffer.Write(Rec.age, SizeOf(Rec.age));
CopyData.dwData := 0;
CopyData.cbData := Buffer.Size;
CopyData.lpData := Buffer.Memory;
SendMessage(Target, wm_CopyData, Source, LParam(@CopyData));
finally
Buffer.free;
end;
end;
수신자가 각 문자에 얼마나 많은 문자가 속하는지 알 수 있도록 문자열의 문자 외에도 문자열의 길이를 씁니다. 받는 사람의 코드는 다음과 같을 것이다 : 그것은 모든 것을 쉽게 이후이 표준이 아닌 TReadOnlyMemoryStream
을 사용했습니다
procedure TBasicForm.WMCopyData(var Message: TWMCopyData);
var
Rec: TMyRec;
Len: Integer;
Buffer: TStream;
begin
Buffer := TReadOnlyMemoryStream.Create(
Message.CopyDataStruct.lpData, Message.CopyDataStruct.cbData);
try
if Message.CopyDataStruct.dwData = 0 then begin
Buffer.Read(Len, SizeOf(Len));
SetLength(Rec.name, Len);
if Len > 0 then
Buffer.Read(Rec.name[1], Len * SizeOf(Char));
Buffer.Read(Len, SizeOf(Len));
SetLength(Rec.add, Len);
if Len > 0 then
Buffer.Read(Rec.add[1], Len * SizeOf(Len));
Buffer.Read(Rec.age, SizeOf(Rec.age));
// TODO: Do stuff with Rec here.
Message.Result := 1;
end else
inherited;
finally
Buffer.Free;
end;
end;
. 간단한 구현 방법은 다음과 같습니다.
type
TReadOnlyMemoryStream = class(TCustomMemoryStream)
public
constructor Create(Mem: Pointer; Size: LongInt);
function Write(const Buffer; Count: LongInt): LongInt; override;
end;
constructor TReadOnlyMemoryStream.Create;
begin
inherited Create;
SetPointer(Mem, Size);
end;
function TReadOnlyMemoryStream.Write;
begin
Result := 0;
end;
고맙습니다. – XBasic3000