프로세스 간의 통신(IPC)은 프로세스 간에 정보를 주고 받을 수 있도록 하는 통신 기법입니다.
프로세스 간의 통신 방법은 서로 간에 메시지를 전달하는 방법과 공유 메모리를 이용하는 방법 그리고 클립보드를 이용하는 방법 등이 있습니다.
1. 프로세스 사이의 메시지 전달
1)동일한 프로그램이 여러 개 실행 중일 때 메시지 전송
RegisterWindowMessage 이용
프로세스 또는 프로그램 간의 메시지 전달은 RegisterWindowMessage(_T”문자열”);로 문자열을 등록한 후 이 함수가 리턴하는 값을 SendMessage 함수나 PostMessage 함수를 이용해서 전달하면 됩니다.
SendMessage(HWND_BROADCAST, 리턴 값, WPARAM, LPARAM)
PostMessage(HWND_BROADCAST, 리턴 값, WPARAM, LPARAM)
그리고 메시지를 받을 윈도우에서는 ON_REGISTERED_MESSAGE(메시지, 메시지처리함수)로 등록하면 됩니다.
예제1)
2) 서로 다른 프로그램 간의 메시지 전달
프로세스 간의 메시지 전달은 FindWindow 함수를 이용해서 특정 윈도우의 핸들을 구한 후 SendMessage나 PostMessage를 이용해서 메시지를 전달하면 됩니다.
이 때는 되도록 사용자정의메시지를 정의해서 사용하는 것이 바람직합니다.
HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);
lpClassName: 클래스 이름
lpWindowName: 프로세스 이름
클래스 이름이나 프로세스 이름으로 윈도우를 찾아서 그 핸들을 리턴해주는 함수
예제)
2. WM_COPYDATA를 이용한 데이터 전달
SendMessage를 이용해서 전송하며 두 번째 인자인 메시지는 WM_COPYDATA를 입력하면 되고 첫 번째 인자는 메시지를 받을 윈도우 핸들이며 세 번째 인자인 WPARAM은 데이터를 전송하는 윈도우 핸들이며 마지막 네번째 LPARAM은 COPYDATASTRUCT 구조체 변수의 주소입니다.
COPYDATASTRUCT {
ULONG_PTR dwData; 전송할 메시지
DWORD cbData; 전달할 데이터의 사이즈
PVOID lpData; 데이터의 주소
}
전송을 받는 프로그램은 WM_COPYDATA를 정의해야 합니다.
이 메시지의 매개 변수 중 pCopyDataStruct가 전달된 구조체의 주소를 넘겨받습니다.
예제)
3. 클립보드를 이용한 통신
클립보드는 윈도우 운영체제의 구성요소로 모든 응용 프로그램이 접근할 수 있는 공유 메모리 영역입니다.
이 영역을 이용해서 데이터를 주고 받을 수 있습니다.
OpenClipboard(윈도우 핸들): 클립보드를 열어주는 함수
윈도우 핸들을 클립보드를 사용할 윈도우 핸들을 넘겨주면 됩니다.
CloseClipboard(): 클립보드를 닫아주는 함수
EmptyClipboard(); 클립보드를 비워주는 함수
SetClipboardData(UINT uFormat, HANDLE hMem);
hMem의 핸들에 해당하는 주소로 uFormat에 맞추어 클립보드에 데이터를 삽입해주는 함수
uFormat은 CF로 시작하는 옵션으로 데이터의 종류를 의미합니다.
GlobalAlloc(옵션, 메모리크기): 힙 메모리를 할당받는 함수
옵션
GMEM_FIXED: 메모리 위치 고정
GMEM_MOVEABLE: 메모리 위치 가변
GMEM_ZEROINIT: 메모리 영역 0으로 초기화
GHND: GMEM_MOVEABLE and GMEM_ZEROINIT.
GPTR: GMEM_FIXED and GMEM_ZEROINIT.
예제)
4. 공유 메모리를 이용한 IPC
프로그램에게 할당되는 메모리 공간은 4GB입니다.
이 중 절반은 사용자에게 할당되고 나머지 절반은 커널(운영체제)에게 할당됩니다.
운영체제에게 할당된 공간은 프로그램이 임의로 접근이 안되지만 이 영역을 이용하여 프로세스 간에 서로 통신할 수 있습니다.
– 공유 메모리의 할당과 초기화
핟당: HANDLE CreateFileMapping
(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCTSTR lpName
); 이용
hFile: 파일의 핸들 – CreateFile()로 생성해서 넘겨주어도 되고 INVALID_HANDLE_VALUE을 넘겨주면 운영체제가 알아서 생성해줍니다.
실제로는 메모리 공간입니다.
lpAttributes은 보안 속성으로 대부분 NULL
flProtect: 접근 모드
PAGE_READONLY, PAGE_READWRITE, PAGE_WRITECOPY, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE 가 정의되어 있습니다.
dwMaximumSizeHigh: 최대 사이즈
dwMaximumSizeLow: 최소 사이즈
lpName: 공유할 이름
이렇게 하면 핸들을 넘겨주게 됩니다.
다른 곳에서 사용하고자 한다면 이름을 일치시켜 사용할 수 있습니다.
– 공유 메모리 영역 생성
공유 메모리 영역의 데이터를 받아올때는 MapViewOfFile함수를 이용합니다.
LPVOID WINAPI MapViewOfFile(
HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
SIZE_T dwNumberOfBytesToMap
);
hFileMappingObject: 읽어올 파일 핸들
dwDesiredAccess: 접근 모드
FILE_MAP_ALL_ACCESS
FILE_MAP_COPY
FILE_MAP_EXECUTE
FILE_MAP_READ
FILE_MAP_WRITE
dwFileOffsetHigh: 64비트 운영체제인 경우 상위 더블워드
dwFileOffsetLow: 64비트 운영체제인 경우 하위 더블워드
dwNumberOfBytesToMap: 사용할 크기
이 함수를 호출하면 공유 영역의 데이터를 현재 프로그램의 데이터로 변경 가능
예제) 공유 메모리에 문자열을 전송하여 각 프로그램이 출력하는 프로그램