데브피아 갔다가 좋은 팁이 있길래 소개 합니다.


보통 프로세스간 메모리를 공유는 memory mapped file을 사용하기 위해 CreateFileMapping 같은 걸 사용하는데

ReadProcessMemory 를 이용해서 공유하는 방법을 간단하게 소개 하겠습니다.


memory mapped file 에 비해 장점이라면

주소만으로 큰 데이터 공유가 가능하다? 정도 겠네요

속도는 잘 모르겠어요


먼저 공유할 메모리를 정의하고, 여기서는 구조체를 사용하도록 해보죠


편의상 데이터를 할당하는 쪽을 서버

데이터를 사용하는 쪽을 클라이언트라고 하면


서버쪽 준비사항은

type

  TMyRecord = record  // 공유할 구조체
    data : array [0..8] of char;
    i : integer;
    d : array[0..16] of char;
  end;
  PMyRecord = ^TMyRecord;
var
  myRecord : PMyRecord;


procedure TForm1.Button1Click(Sender: TObject);
var
  dwProcessId : cardinal;
begin
  New(myRecord); //구조체 메모리를 할당해주고
  myRecord^.data := 'aaaa';
  myRecord^.i := 3434;
  myRecord^.d := 'cccc';
//  ReadProcessMemory 를 이용하기 위해서는 프로세스 아이디하고, 사용할 메모리 주소를 알아야 합니다.
// 간단하게 테스트 하기 위해 Edit 에 넣고 클라이언트에서 그냥 붙혀넣기로 했습니다. 쿨럭 ;;;;
  GetWindowThreadProcessId(Handle, dwProcessId );
  Edit1.Text := inttostr(dwProcessId);  // 서버쪽 프로세스 ID
  Edit2.Text := inttohex(integer(myRecord),8); // 공유할 데이터 Address
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
// 정말 메모리가 공유 되는지 확인해 보아요
  myRecord^.i := myRecord^.i + 1;
end;

 

이제 클라이언트는 서버의 데이터를 쓰기위해 서버로부터 메모리 주소를 받기만 하면 되겠군요
메모리 주소는 레지스트리나 ini 에 써두면 되겠군요

클라이언트는 이렇게

type
  TMyRecord = record
    data : array [0..8] of char;
    i : integer;
    d : array[0..16] of char;
  end;

procedure TForm2.GetMemClick(Sender: TObject);
var
  m_hProcess : THandle;
  myRecord : TMyRecord;
  ReadBytes : cardinal;
  pid : integer;
  ShareMemaddr : pointer;
begin
// 귀찮아서 이리 했으니 양해를 ;;;;
  pid := 7608;  // 서버측의 Edit1.text 값이 되겠군요
  ShareMemaddr := pointer($011A1C70); // 서버측의 Edit2.text 값이 되겠네요

  m_hProcess := OpenProcess(PROCESS_VM_READ, FALSE, pid);
  if ReadProcessMemory(m_hProcess, ShareMemaddr , @myRecord, sizeof(TMyRecord), ReadBytes) then
  begin
    button1.Caption := inttostr(ReadBytes);
    Caption := myRecord.data + '  ' + inttostr(myrecord.i) + ' ' + myrecord.d;
  end
  else
    ShowMessage('server down');

end;