티스토리 뷰

System Programming

[system programming] IPC 메세지, COPYDATASTRUCT

열혈허슬러 상추님 2019.07.05 17:04
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);
}
 
댓글
댓글쓰기 폼
네이버 이웃추가
«   2019/10   »
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
글 보관함