프로세스간 통신 (Inter Process Communication, IPC) 란?
서로 다른 프로세스에서 정해진 규칙에 의해서 데이터를 주고 받는 행위를 의미합니다.
IPC 방법은 여러 가지가 있지만 가장 많이 사용하는 [SendMessage / PostMessage], [WM_COPYDATA], [Memory Mapped File] 3가지 방식에 대해서 설명 드리겠습니다.
1. SendMessage / PostMessage
■ 송신측 (Send)
# cpp file
static const UINT regMsg = ::RegisterWindowMessage(_T("SendMessageTest"));
int nMsg = 100;
::SendMessage(HWND_BROADCAST, regMsg, (WPARAM)nMsg, 0);
//::PostMessage(HWND_BROADCAST, regMsg, (WPARAM)msg, 0);
■ 수신측 (Receive)
# header file
afx_msg LRESULT OnMessage(WPARAM wParam, LPARAM lPararm);
# cpp file
static const UINT regMsg = ::RegisterWindowMessage(_T("SendMessageTest"));
BEGIN_MESSAGE_MAP(CReceiveDlg, CDialogEx)
ON_REGISTERED_MESSAGE(regMsg, OnMessage)
END_MESSAGE_MAP()
LRESULT CReceiveDlg::OnMessage(WPARAM wParam, LPARAM lParam)
{
int temp = (int)lParam;
CString msg;
msg.Format(_T("%d"), temp);
AfxMessageBox(msg);
return 0L;
}
SendMessage와 PostMessage의 차이
SendMessage는 동기 방식으로 메세지를 보내고 수신측에서 처리가 될때까지 기다리는 것이고
PostMessage는 비동기 방식으로 메세지를 보내고 수신측에서 받았든 못받았든 다음 프로세스를 진행하는 것입니다.
문자열 전달
문자열 전달은 주소 값을 보내야하는데 만약 같은 프로그램에서 OnMessage로 SendMesssage에서 전달된 값을 받는다면 가능하겠지만 송신, 수신 프로그램은 다른 메모리 공간을 가지고 있기 때문에 불가능합니다.
따라서, SendMessage / PostMessage 방식은 단순히 다른 프로그램을 호출하거나 값 전달 없이 정의된 번호(int)로 특정 기능을 실행한다던가 하는 경우에 사용할 수 있겠습니다.
다음에 소개할 두 방법은 메모리 공간을 공유하기 때문에 문자열 전달도 가능하니 값 전달이 필요한 경우 다음 두가지 방법 중에 선택해서 사용하면 됩니다.
2. WM_COPYDATA
■ 송신측 (Send)
# cpp file
CString str = _T("테스트");
COPYDATASTRUCT cds;
cds.dwData = 100;
cds.cbData = sizeof(TCHAR) * (_tcslen(str) + 1);
cds.lpData = (TCHAR*)(LPCTSTR)str;
::SendMessage(hWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
* hWnd 값은 FindWindow로 수신 프로그램의 HWND를 찾아서 SendMessage를 보내면 됩니다.
■ 수신측 (Receive)
# header file
afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);
# cpp file
BEGIN_MESSAGE_MAP(CReceiveDlg, CDialogEx)
ON_WM_COPYDATA()
END_MESSAGE_MAP()
BOOL CReceiveDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
COPYDATASTRUCT* cds = pCopyDataStruct;
if (cds->dwData == 100)
{
TCHAR* lpBuffer = (TCHAR*)cds->lpData;
CString str(lpBuffer);
}
return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);
}
3. Memory Mapped File
■ 송신측 (Send)
# cpp file
static CString sName = _T("MemoryMapTest");
HANDLE hHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAX_PATH, sName);
if (hHandle == NULL)
return;
LPCTSTR lpMapping = (LPTSTR)MapViewOfFile(hHandle, FILE_MAP_ALL_ACCESS, 0, 0, MAX_PATH);
if (lpMapping == NULL)
return;
CString str = _T("테스트");
memcpy((PVOID)lpMapping, str, _tcslen(str) * sizeof(TCHAR));
UnmapViewOfFile(lpMapping);
■ 수신측 (Receive)
# cpp file
static CString sName = _T("MemoryMapTest");
HANDLE hHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, sName);
if (hHandle == NULL)
return;
LPCTSTR lpMapping = (LPCTSTR)MapViewOfFile(hHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (lpMapping == NULL)
{
CloseHandle(hHandle);
return;
}
UnmapViewOfFile(lpMapping);
CloseHandle(hHandle);
'C++, MFC' 카테고리의 다른 글
[C++/MFC] qsort를 이용하여 배열 정렬하기 (int[], CStringArray, CPtrArray) (0) | 2022.10.05 |
---|---|
[MFC] 프로그램 내부에서 다른 프로그램(exe, msi) 설치하는 방법 / exe, msi 설치 옵션 (1) | 2022.09.29 |
[C++/MFC] 인코딩, 유니코드 구분해서 CFile로 txt파일 읽는 방법 (0) | 2022.09.22 |
[C++/MFC] 멀티바이트, 유니코드 개념 정리 / 문자열 변환 방법 (1) | 2022.09.19 |
[C++/MFC] 텍스트 파일의 인코딩 확인하는 방법 (0) | 2022.09.16 |
댓글