IPC (Inter Process Communication)
»ç¿ëÀÚÀÇ ¿ä±¸°¡ Áõ´ëµÇ¸é¼ ÇÁ·Î±×·¥ÀÌ °®Ãç¾ß ÇÒ ±â´É ¶ÇÇÑ ¸¹¾ÆÁö°í ´ç¿¬È÷ ÇÁ·Î±×·¥ Å©±âµµ ºñ´ëÇØÁ³´Ù. ¶ÇÇÑ ÇϳªÀÇ ÇÁ·Î±×·¥¸¸À¸·Î´Â »ç¿ëÀÚÀÇ ¿å±¸¸¦ ÃæÁ·½ÃŰÁö ¸øÇØ ¿©·¯°³ÀÇ ÇÁ·Î±×·¥À» ¸¸µé¾î¾ß ÇÏ´Â »óȲÀÌ ¹ß»ýÇϰí ÀÖ´Ù. ¿©±â¼ ¼·Î ´Ù¸¥ ÇÁ·Î±×·¥ (¾ö¹ÐÈ÷ ¾ê±âÇϸé ÇÁ·Î¼¼½º)µé°£¿¡ µ¥ÀÌÅ͸¦ ±³È¯Çϰųª ƯÁ¤ ±â´ÉÀ» »ç¿ëÇÏ·Á¸é ¾î¶»°Ô ÇØ¾ß ÇÒ±î? ÀÌ·± ¹®Á¦¸¦ ÇØ°áÇϱâ À§ÇÑ °ÍÀÌ ´ÙÀ½¿¡ ¼Ò°³µÇ´Â IPC ±â¼ú(ÇÁ·Î¼¼½º°£ Åë½Å¹æ¹ý) ÀÌ´Ù.
SendMessage() / PostMessage() : »ç¿ëÀÚ Á¤ÀÇ ¸Þ½ÃÁö, ½Ã½ºÅÛ µî·Ï ¸Þ½ÃÁö
WM_COPYDATA, Atom µîÀ» ÀÌ¿ëÇÏ´Â ¹æ¹ý
DLL (Dynamic Link Library) °øÀ¯
µ¿Àû ÀÚ·á ±³È¯ (Dynamic Data Exchange : DDE)
OLE ÀÚµ¿È (Automation)
¸Þ¸ð¸® ¸Ê ÆÄÀÏ (Memory Map File)
NetBIOS
³×ÀÓµå ÆÄÀÌÇÁ (Named Pipe)
¸ÞÀÏ ½½·Ô (Mail Slot)
À§¿¡ ³ª¿µÈ IPC¿¡´Â µ¿ÀÏ ½Ã½ºÅÛ(·ÎÄà ½Ã½ºÅÛ)¿¡¼¸¸ »ç¿ëµÇ´Â °ÍÀÌ ÀÖ°í, ´Ù¸¥ ½Ã½ºÅÛ(¸®¸ðÆ® ½Ã½ºÅÛ)¿¡¼µµ ÀÛµ¿µÇ´Â °ÍÀÌ ÀÖ´Ù.
´ÙÀ½ÀÇ ¿¹Á¦´Â wParam°ú lParam µÎ º¯¼ö¸¦ ÀÌ¿ëÇØ¼ µ¥ÀÌÅÍ Àü¼ÛÀÌ °¡´ÉÇÏ´Ù. ÀÌ µÎ º¯¼öÀÇ Å©±â´Â ´ÙÀ½°ú °°´Ù.
WPARAM == unsigned int (UINT)
: À©µµ¿ì 3.0 / 3.1 °°Àº 16ºñÆ® À©µµ¿ì¿¡¼´Â 16ºñÆ®(2¹ÙÀÌÆ®)À̰í, Win32 (32ºñÆ® À©µµ¿ì)¿¡¼´Â 32ºñÆ®(4¹ÙÀÌÆ®)ÀÇ °ªÀ» °¡Áø´Ù.
LPARAM == long
: 16ºñÆ®³ª 32ºñÆ® ¸ðµÎ 32ºñÆ®(4¹ÙÀÌÆ®)ÀÇ °ªÀ» °¡Áø´Ù.
¸¸¾à µ¥ÀÌÅͰ¡ 4¹ÙÀÌÆ®°¡ ³ÑÀ» °æ¿ì, °°Àº ÇÁ·Î¼¼½º ³»¿¡¼´Â ±¸Á¶Ã¼¿¡ Á¤º¸¸¦ ´ã°Å³ª ¸Þ¸ð¸®¸¦ ÇÒ´çÇØ¼ Á¤º¸¸¦ ÀúÀåÇÑ ÈÄ À̰ÍÀÇ Æ÷ÀÎÅ͸¦ lParamÀ» ÅëÇØ Àü´ÞÇÏ¸é µÈ´Ù. ÇÏÁö¸¸ ´Ù¸¥ ÇÁ·Î¼¼½º °£¿¡´Â ÀÌ·±½ÄÀº ºÒ°¡´ÉÇÏ°í ¸Þ¸ð¸® ¸ÊÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.
1. SendMessage() / PostMessage() »ç¿ë
a) RegisterWindowMessage()¸¦ »ç¿ëÇÒ °æ¿ì
RegisterWindowMessage() ÇÔ¼ö´Â ½Ã½ºÅÛ¿¡ À¯ÀÏÇÑ »õ À©µµ¿ì ¸Þ½ÃÁö¸¦ Á¤ÀÇÇÏ°í µî·ÏÇÑ´Ù. ¸®ÅϵǴ ¸Þ½ÃÁö °ªÀº SendMessage() ³ª PostMessage() °°Àº ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
UINT RegisterWindowMessage(
LPCTSTR lpString // address of message string
);
ÀÌ ÇÔ¼öÀÇ ¿øÇüÀº À§¿Í °°´Ù. ÀÌ ÇÔ¼öÀÇ ÀÎÀڷδ ¸Þ½ÃÁö¸¦ ÁÖ°í¹ÞÀ» ÇÁ·Î±×·¥³¢¸® ¹Ì¸® ¾à¼ÓÇÑ ¹®ÀÚ¿À» ³Ñ°ÜÁØ´Ù. °°Àº ¹®ÀÚ¿À» ÀÌ¿ëÇÏ¿© ¸Þ½ÃÁö¸¦ µî·ÏÇÑ ÇÁ·Î±×·¥³¢¸®¸¸ ¼·Î ¸Þ½ÃÁö¸¦ ÁÖ°í¹ÞÀ» ¼ö ÀÖ°Ô µÇ´Âµ¥, ÀÌ ÇÔ¼öÀÇ ¹Ýȯ°ªÀ» ´Ù¸¥ ÇÁ·Î±×·¥¿¡ Àü´ÞÇÒ ¸Þ½ÃÁö·Î ÀÌ¿ëÇÏ¸é µÈ´Ù.
== ÀÌÁ¦ ù ¹øÂ° ¿¹Á¦¸¦ ¸¸µé¾îº¸ÀÚ==
1) °£´ÜÇÏ°Ô Å×½ºÆ®Çϱâ À§ÇØ ´ÙÀ̾ó·Î±× º£À̽º(Dialog based)·Î ÇÁ·ÎÁ§Æ®¸¦ Çϳª ¸¸µç´Ù. ÇÁ·ÎÁ§Æ®¸íÀº IPC1 ÀÌ´Ù.
2) ¸®ÅϵǴ ¸Þ½ÃÁö °ªÀ» ÀúÀåÇϱâ À§ÇÑ º¯¼ö(nRegMsg)¸¦ IPC1Dlg.cpp ÆÄÀÏ¿¡ ´ÙÀ½Ã³·³ Àü¿ªÀ¸·Î ÁöÁ¤ÇÑ´Ù.
UINT nRegMsg;
class CAboutDlg :
public CDialog
{
public:
......................
......................
}
À§ÀÇ ¿¹Ã³·³ cppÆÄÀÏÀÇ class Á¤ÀǺΠÀ§¿¡ º¯¼ö¸¦ Á¤ÀÇÇÑ´Ù¸é ¹«³ÇϰڴÙ.
3) ÃʱâÈ ÇÔ¼öÀÎ OnInitDialog() ÇÔ¼ö¿¡¼ ¸Þ½ÃÁö¸¦ µî·ÏÇÑ´Ù.
¸¸¾à
SDI Çü½ÄÀ̶ó¸é OnInitialUpdate() ÇÔ¼ö¿¡¼ ÀÌ ÀÛ¾÷À» ÇÏ¸é µÇ°Ú´Ù.
BOOL CIPC1Dlg::OnInitDialog()
{
...........................
...........................
//
TODO: Add extra initialization here
nRegMsg
= ::RegisterWindowMessage("This is IPC sample program1");
return
TRUE; // return TRUE unless you set the focus to a control
}
4) ´ÙÀ½°ú °°ÀÌ ´ÙÀ̾ó·Î±× ÅÛÇø´À» ¸¸µç´Ù. "Ãë¼Ò" ¹öưÀº Áö¿ì°í, "È®ÀÎ" ¹öưÀº ĸ¼Ç¸¸ "Á¾·á" ¶ó°í °íÄ£´Ù. ¿©±â¼ ¿ÞÂʰú ¿À¸¥ÂÊÀÇ ¿¡µðÆ®¹Ú½ºÀÇ ID´Â °¢°¢ IDC_EDIT_WPARAM, IDC_EDIT_LPARAM À̰í "Àü¼Û" ÀÌ¶ó ¾²ÀÎ ¹öưÀÇ ID´Â IDC_SEND ÀÌ´Ù.

5) Ŭ·¡½º À§Àúµå¸¦ ¿¾î¼ µÎ ¹øÂ° ÅÇ Member Variables¸¦ ¼±ÅÃÇϰí, µÎ °³ÀÇ ¿¡µðÆ® ¹Ú½º¿Í ¿¬°áµÇ´Â º¯¼ö¸¦ ´ÙÀ½°ú °°ÀÌ ÁöÁ¤ÇÑ´Ù.
|
Control IDs: IDC_EDIT_LPARAM |
Type: long |
Member: m_lParam |
6) ´ÙÀ½Àº IDC_SEND ¹öư¿¡ ´ëÇÑ Çڵ鷯ÀÌ´Ù. ¿©±â¼ »ç¿ëµÇ´Â SendMessage()ÀÇ Ã¹ ¹øÂ° ÀÎÀÚ´Â ¹Ýµå½Ã HWND_BROADCST À̾î¾ß ÇÑ´Ù.
SendMessage()ÀÇ Ã¹¹øÂ° ÀÎÀÚ°¡ HWND_BROADCSTÀÎ °æ¿ì ¸Þ½ÃÁö´Â ½Ã½ºÅÛ»óÀÇ ¸ðµç top-level À©µµ¿ì¿¡ Àü´ÞµÈ´Ù. ¿©±â¿¡´Â disabled ¶Ç´Â invisible µÇ¾î Àְųª, ÁßøµÇ¾î Àְųª(overlapped), pop-up À©µµ¿ìµµ Æ÷ÇԵȴÙ. ÇÏÁö¸¸ Â÷Àϵå À©µµ¿ì¿¡´Â ¸Þ½ÃÁö°¡ Àü´ÞµÇÁö ¾Ê´Â´Ù.
¿©±â±îÁö°¡ ¼Û½Å ÇÁ·Î±×·¥¿¡ ´ëÇÑ ³»¿ëÀÌ´Ù.
void CIPC1Dlg::OnSend()
{
//
TODO: Add your control notification handler code here
UpdateData();
::SendMessage(HWND_BROADCAST,
nRegMsg, (WPARAM)m_wParam, (LPARAM)m_lParam);
}
7) ¿©±â¼ºÎÅÍ´Â ¼ö½Å ÇÁ·Î±×·¥¿¡ °üÇÑ ³»¿ëÀÌ´Ù.
´ÙÀ½°ú °°ÀÌ IPC1Dlg.cpp ÆÄÀÏÀÇ ¸Þ½ÃÁö¸Ê ºÎºÐ¿¡ ´ÙÀ½Ã³·³ ON_REGISTERED_MESSAGE ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇÏ¿© µî·ÏÇÑ ¸Þ½ÃÁö¿Í Çڵ鷯¸¦ ¿¬°á½ÃŲ´Ù.
BEGIN_MESSAGE_MAP(CIPC1Dlg, CDialog)
//{{AFX_MSG_MAP(CIPC1Dlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_SEND,
OnSend)
//}}AFX_MSG_MAP
ON_REGISTERED_MESSAGE(nRegMsg,
OnRegMsg) // Ãß°¡
END_MESSAGE_MAP()
8) ´ÙÀ½Àº ¸Þ½ÃÁö¸Ê¿¡ Ãß°¡ÇÑ ¸Þ½ÃÁö¿¡ ¿¬°áµÇ´Â Çڵ鷯¸¦ ½ÇÁ¦·Î ÀÛ¼ºÇÑ´Ù.
LRESULT CIPC1Dlg::OnRegMsg(WPARAM wParam, LPARAM lParam)
{
m_wParam
= wParam;
m_lParam =
lParam;
UpdateData(FALSE);
return
0L;
}
9) ÀÌ·¸µí ÇϳªÀÇ ÇÁ·Î±×·¥¿¡ ¼Û¼ö½Å ºÎºÐÀ» ´Ù ³ÖÀ» ¼öµµ ÀÖÁö¸¸, µÎ °³ÀÇ ÇÁ·Î±×·¥À» µû·Î ¸¸µé ¼öµµ ÀÖ´Ù. µû·Î ¸¸µç´Ù¸é ¼Û½Å ÇÁ·Î±×·¥Àº 1~6¹ø±îÁö¸¦ Àû¿ëÇÏ¸é µÇ°í, ¼ö½Å ÇÁ·Î±×·¥Àº 2, 3, 7, 8¹øÀ» Àû¿ëÇÏ¸é µÈ´Ù.
b) FindWindow()¸¦ »ç¿ëÇÒ °æ¿ì
FindWindow()ÀÇ ÇÔ¼ö ¿øÇüÀº ´ÙÀ½°ú °°´Ù.
static CWnd* PASCAL FindWindow( LPCTSTR
lpszClassName, LPCTSTR lpszWindowName );
FindWindow() ÇÔ¼ö´Â ÀÎÀڷΠŬ·¡½º À̸§°ú À©µµ¿ì ĸ¼ÇÀ» ÁÖ°í, ±×¿¡ ÇØ´çÇÏ´Â À©µµ¿ì¸¦ ã´Â´Ù. ¸ðµç top-levelÀÇ À©µµ¿ì¸¦ ãÁö¸¸, Â÷Àϵå À©µµ¿ì´Â ãÁö ¸øÇÑ´Ù. ÇØ´çÇÏ´Â À©µµ¿ì°¡ ¾øÀ¸¸é NULL°ªÀÌ ¸®ÅϵȴÙ. ¸¸¾à lpszClassNameÀÌ NULLÀ̸é À©µµ¿ì ĸ¼Ç¿¡ ÇØ´çÇÏ´Â À©µµ¿ì¸¸ ã°í, lpszWindowNameÀÌ NULLÀ̸é ÁÖ¾îÁø Ŭ·¡½º À̸§¿¡ ÇØ´çÇÏ´Â À©µµ¿ì¸¦ ã´Â´Ù.
== ¿©±â¼ µÎ ¹øÂ° ¿¹Á¦¸¦ ¸¸µé¾îº¸ÀÚ==
¼Û½Å ÇÁ·Î±×·¥ ¿¹Á¦ ¼ö½Å ÇÁ·Î±×·¥ ¿¹Á¦
1) ¸ÕÀú ¼Û½Å ÇÁ·Î±×·¥À» ¸¸µé¾îº¸ÀÚ. ¿©±â¼´Â ¼Û¼ö½Å ÇÁ·Î±×·¥À» º°µµ·Î ¸¸µç´Ù. ´ÙÀ̾ó·Î±× º£À̽ºÀÇ ÇÁ·ÎÁ§Æ®¸¦ Çϳª ¸¸µç´Ù. ÇÁ·ÎÁ§Æ®¸íÀº IPC2ÀÌ´Ù.
2) ´ÙÀ½°ú °°ÀÌ ´ÙÀ̾ó·Î±× ÅÛÇø´À» ¸¸µç´Ù. "Ãë¼Ò" ¹öưÀº Áö¿ì°í, "È®ÀÎ" ¹öưÀº ĸ¼Ç¸¸ "Á¾·á" ¶ó°í °íÄ£´Ù. ¿©±â¼ ¿ÞÂʰú ¿À¸¥ÂÊÀÇ ¿¡µðÆ®¹Ú½ºÀÇ ID´Â °¢°¢ IDC_EDIT_WPARAM, IDC_EDIT_LPARAM À̰í "Àü¼Û" ÀÌ¶ó ¾²ÀÎ ¹öưÀÇ ID´Â IDC_SEND ÀÌ´Ù.
À̰ÍÀº À§ ù ¹øÂ° ¿¹Á¦ÀÇ 4¹ø°ú µ¿ÀÏÇÏ´Ù. ¼Û½Å ÇÁ·Î±×·¥¿¡¼ ĸ¼ÇÀº »ó°ü¾ø´Ù.

3) Ŭ·¡½º À§Àúµå¸¦ ¿¾î¼ µÎ ¹øÂ° ÅÇ Member Variables¸¦ ¼±ÅÃÇϰí, µÎ °³ÀÇ ¿¡µðÆ® ¹Ú½º¿Í ¿¬°áµÇ´Â º¯¼ö¸¦ ´ÙÀ½°ú °°ÀÌ ÁöÁ¤ÇÑ´Ù.
ÀÌ°Í ¶ÇÇÑ À§ ù ¹øÂ° ¿¹Á¦ÀÇ 5¹ø°ú µ¿ÀÏÇÏ´Ù.
|
Control IDs: IDC_EDIT_LPARAM |
Type: long |
Member: m_lParam |
4) IPC2Dlg.cpp ÆÄÀÏÀÇ »ó´Ü¿¡ ´ÙÀ½°ú °°ÀÌ »ç¿ëÀÚ Á¤ÀÇ ¸Þ½ÃÁö¸¦ Á¤ÀÇÇÑ´Ù.
#define WM_MY_MESSAGE WM_USER+7
»ç¿ëÀÚ Á¤ÀÇ ¸Þ½ÃÁö´Â "Visual C - MFC" ÀÇ "WM_USER ¸Þ½ÃÁö" ºÎºÐÀ» Âü°íÇÏ¸é µÈ´Ù.
WM_USER ´ÙÀ½¿¡ ´õÇÏ´Â ¼ýÀÚ´Â ¼Û¼ö½Å ÇÁ·Î±×·¥¿¡¼ ¸ðµÎ °°ÀÌ ¸ÂÃß¾îÁֱ⸸ Çϸé ÁöÁ¤µÈ ¹üÀ§³»ÀÇ ¾Æ¹«·± ¼ýÀÚ¶óµµ »ó°ü¾ø´Ù.
5) ´ÙÀ½À¸·Î "Àü¼Û" ¹öư¿¡ ´ëÇÑ Çڵ鷯¸¦ ÀÛ¼ºÇÑ´Ù. ¿©±â±îÁö°¡ ¼Û½Å ÇÁ·Î±×·¥¿¡ ´ëÇÑ ¼³¸íÀÌ´Ù.
void CIPC2Dlg::OnSend()
{
//
TODO: Add your control notification handler code here
CWnd
*pWnd = CWnd::FindWindow(NULL, "IPC_RECEIVE");
if(!pWnd)
{
AfxMessageBox("Program
is not found.");
return;
}
UpdateData();
pWnd->SendMessage(WM_MY_MESSAGE,
m_wParam, m_lParam);
}
6) ÀÌÁ¦ ¼ö½Å ÇÁ·Î±×·¥À» ¸¸µé¾îº¸ÀÚ.
¿ª½Ã °£´ÜÈ÷ ±¸ÇöÇϱâ À§ÇØ ÇÁ·ÎÁ§Æ® ¸íÀÌ IPC3ÀÎ ´ÙÀ̾ó·Î±× º£À̽º ÇÁ·ÎÁ§Æ®¸¦ ¸¸µç´Ù.
7) IPC3Dlg.cpp ÆÄÀÏÀÇ »ó´Ü¿¡ ´ÙÀ½°ú °°ÀÌ »ç¿ëÀÚ Á¤ÀÇ ¸Þ½ÃÁö¸¦ Á¤ÀÇÇÑ´Ù.
#define WM_MY_MESSAGE WM_USER+7
¼Û¼ö½Å ÇÁ·Î±×·¥¿¡¼ ¹Ýµå½Ã °°Àº ¸Þ½ÃÁö¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù.
8) ´ÙÀ̾ó·Î±× ÅÛÇø´À» ´ÙÀ½°ú °°ÀÌ ¸¸µç´Ù. ¿¡µðÆ® ¹Ú½ºÀÇ ID´Â ¿ÞÂÊ¿¡¼ºÎÅÍ IDC_EDIT_WPARAM, IDC_EDIT_LPARAM ·Î ÇÑ´Ù. ±×¸®°í ¹Ýµå½Ã ¾Æ·¡ ±×¸²°ú °°ÀÌ Ä¸¼ÇÀ» IPC_RECEIVE¶ó°í °íÄ£´Ù.

9) Ŭ·¡½º À§Àúµå¸¦ ¿¾î¼ µÎ ¹øÂ° ÅÇ Member Variables¸¦ ¼±ÅÃÇϰí, µÎ °³ÀÇ ¿¡µðÆ® ¹Ú½º¿Í ¿¬°áµÇ´Â º¯¼ö¸¦ ´ÙÀ½°ú °°ÀÌ ÁöÁ¤ÇÑ´Ù.
|
Control IDs: IDC_EDIT_LPARAM |
Type: long |
Member: m_lParam |
10) IPC3Dlg.cpp ÆÄÀÏÀÇ ¸Þ½ÃÁö¸Ê ºÎºÐ¿¡ ´ÙÀ½°ú °°ÀÌ ÇÑ ÁÙ Ãß°¡ÇÑ´Ù.
BEGIN_MESSAGE_MAP(CIPC3Dlg, CDialog)
//{{AFX_MSG_MAP(CIPC3Dlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MY_MESSAGE,
OnMyMessageProc) // Ãß°¡
END_MESSAGE_MAP()
11) À§ÀÇ ¸Þ½ÃÁö¸Ê¿¡ ¿¬°áµÇ´Â Çڵ鷯¸¦ ÀÛ¼ºÇÑ´Ù.
LRESULT CIPC3Dlg::OnMyMessageProc(WPARAM wParam, LPARAM lParam)
{
m_wParam
= wParam;
m_lParam =
lParam;
UpdateData(FALSE);
return
0L;
}
12) ¼Û¼ö½Å ÇÁ·Î±×·¥ µÎ °³¸¦ °°ÀÌ ½ÇÇàÇÑ ´ÙÀ½ ¼Û½Å ÇÁ·Î±×·¥¿¡¼ Àü¼Û ¹öưÀ» ´·¯ µ¥ÀÌÅ͸¦ º¸³»¸é µÈ´Ù.
- The end of this article -