190704-1
교육을 받으면서 노트필기 했던 내용을 날것 그대로 업로드합니다.
30. IPC(메시지)
Inter process communication
프로세스 간에 통신을 해봅시다.
1 - 메세지를 사용한 교환방식
윈도우즈os 만의 RPC라는 개념이 만들어져서 사용했다.
유저 오브젝트 : Window 같은 것들. 핸들이 전역적으로 사용가능하다.
프로세스는 독립적인 가상 공간을 가진다. 32bit애플리케이션이라면 주소가 00000000~FFFFFFFF 까지 가진다.프로세스는 모두 가상주소공간이라는 주소를 사용한다. 내부적으로는 os만 안다. (64비트면 F가 16개다.) 윈도우의 핸들을 알면 메세지를 보낼 수 있다.
큰 데이터를 보내려고 가상주소를 다른 프로세스에 날리면 다른 프로세스에는 해당 데이터가 없다. 가상 공간은 독립적이기 때문이다.(독립적인 주소공간을 갖기 때문이다.)
위와 같아서 참조를 날려도 참조할 수 없다.
31. IPC(메시지WM_COPYDATA)
OS와 나사이에 약속을 해 놓은 것이다. 메세지는 보낼 수 있는 크기가 정해져있다.
A,B프로세스가 있으면
WM_COPYDATA 메세지가 발생할 당시에만 유효하다
#include <windows.h>
#pragma region MyRegion
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
생략
char titleName[100];
wsprintf(titleName,"%d", GetCurrentProcessId());
생략
}
#pragma endregion
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch (iMsg)
{
case WM_CREATE:
CreateWindow("edit", NULL, WS_VISIBLE|WS_BORDER|WS_CHILD|ES_AUTOHSCROLL,
50,50, 200, 25, hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance,NULL);
CreateWindow("edit", NULL, WS_VISIBLE|WS_BORDER|WS_CHILD|ES_AUTOHSCROLL,
300,50, 300, 25, hwnd, (HMENU)10, ((LPCREATESTRUCT)lParam)->hInstance,NULL);
CreateWindow("button", "메시지 보내기", WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,
50,100, 150, 25, hwnd, (HMENU)2, ((LPCREATESTRUCT)lParam)->hInstance,NULL);
break;
case WM_COPYDATA:
{
char buf[500];
PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;
//* PCOPYDATASTRUCT에서 앞에 P는 Pointer를 의미합니다.
wsprintf(buf, "pid:%d, 정수:%d, 문자열:%s", wParam, pcds->dwData, (char*)pcds->lpData);
SetDlgItemText(hwnd, 1, buf);
//Sleep(2000); //* 실험: 메세지를 받고나서 잡고있기 때문에 창 제어불가능하다.
// pcds는 break; 전 까지 유효하다
}
break;
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case 2: // 보내기
{
char title[100]="";
char string[500]=""; //*입력한 문자열
GetDlgItemText(hwnd,1, title, 100);
GetDlgItemText(hwnd,10, string, 500);
COPYDATASTRUCT cds; //* CDS
cds.dwData = 100; // 전달할 정수값
cds.lpData = string; // 실제 데이터의 주소 명시
cds.cbData = strlen(string)+sizeof(TCHAR); // 널문자가 멀티,유니 에서 다를 수 있으므로 이와 같이 작성한다.
HWND hwnd = FindWindow(NULL,title);
if(NULL != hwnd )
SendMessage(hwnd, WM_COPYDATA, GetCurrentProcessId(), (LPARAM)&cds);
//* 만든 구조체 cds의 주소를 첨부해 WM_COPYDATA 메세지를 보낸다.
//*SendMessage는 dispatch 되어야 반환한다.
}
break;
}
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
// 이곳에서 출력이 이루어짐
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
'System Programming' 카테고리의 다른 글
[system programming] 파이프, 양방향 이름있는 파이프(named pipe) (0) | 2019.07.06 |
---|---|
[system programming] CHECKER3.C -- Mouse Hit-Test Demo Program No. 3 (0) | 2019.07.05 |
[system programming] 플래그, 자원 관리 클래스 (0) | 2019.07.05 |
[system programming] 유저, 커널모드 동기화 (크리티컬 섹션, 뮤텍스, 세마포어, 이벤트 등) (0) | 2019.07.05 |
[system programming] __declspec(thread) (0) | 2019.07.05 |