进程通信
1 进程通信 1.1 SendMessage 消息 WM_COPYDATA LRESULT SendMessage( HWND hWnd, // handle to destination window WM_COPYDATA, // message to send WPARAM wParam, // handle to window (HWND)//发送方或返回消息接收方窗口句柄 LPARAM lParam // data (PCOPYDATASTRUCT) ); typedef struct tagCOPYDATASTRUCT { ULONG_PTR dwData; //消息标签 DWORD cbData; //消息内容大小 PVOID lpData; //消息内容地址 } COPYDATASTRUCT, *PCOPYDATASTRUCT; 只能使用Sendmessage方式,原因在于 WM_COPYDATA 需要两次COPY(进程A->OS,OS->进程B) Sendmessage方式待执行完成后才返回,这样确保OS->进程B 的拷贝过程正确执行;而Postmessage投递消息后即返回,可能在OS->进程B拷贝前或正在拷贝时资源已经释放。另外Sendmessage的switch case中其首项即是WM_COPYDATA,若匹配即开展申请空间等工作;而Postmessage的switch case中并没有WM_COPYDATA比较项。 进程A->OS,操作系统执行 OS->进程B,手工代码完成 适用于数据量较小的场合。 传递只读数据,不提供继承同步方式。 //define WM_COPYDATA communication tag,Process communicated must both set same #define WM_COPYDATA_TAG 0x0 //send { //data sended char szBuff[] = "WM_COPYDATA,only send data read only,from A"; COPYDATASTRUCT cds; cds.dwData = WM_COPYDATA_TAG; cds.cbData = sizeof(szBuff); cds.lpData = szBuff; HWND hRecv = ::FindWindow(NULL, "PA_Copy"); if (hRecv) { ::SendMessage(hRecv, WM_COPYDATA, (WPARAM)m_hWnd, (LPARAM)&cds); } } //receive //rewrite WM_COPYDATA to receive msg BOOL CxxDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { if ( WM_COPYDATA_TAG == pCopyDataStruct->dwData ) { m_strWMCOPYDATA.Format("%s", (char*)pCopyDataStruct->lpData); } return CDialog::OnCopyData(pWnd, pCopyDataStruct); } 1.2 动态库共享段 Microsoft 并不鼓励使用共享段。 1.用这种方法共享内存有可能破坏系统的安全。 2.共享变量意味着一个应用程序中的错误可能影响另一个应用程序的运行,因为它没有办法防止某个应用程序将数据随机写入一个数据块。 dll.cpp //define data segment #pragma data_seg("ShareDll") //... char g_szBuff[1024] = "Some Shared Global Variable";//share data char g_szSynch[32] = "Synchronized Event";//synchronized event name //... #pragma data_seg() //set data segment as share //#pragma comment(comment-type, ["string"]) //parameter 1,comment-type,one of compiler,lib,linker֮һ //parameter 2,additional information for parameter 1 //compiler, ignored by linker //lib, //linker,/SECTION:name,attributes,must have no unnecessary blank space #pragma comment(linker, "/SECTION:ShareDll,RWS") dll.def EXPORTS g_szSynch g_uBuffLen g_szBuff if (!m_hMod) { m_hMod = LoadLibrary("../Debug/ShareDll.dll"); } if (m_hMod) { FreeLibrary(m_hMod);//程序退出时关闭 m_hMod = NULL; } //share dll read char szBuff[1024] = {0}; ULONG uReadLen = 1024; if (m_hMod) { char* g_szSynchR = (char*)GetProcAddress(m_hMod, "g_szSynch"); char* g_szBuffR = (char*)GetProcAddress(m_hMod, "g_szBuff"); ULONG* g_puBuffLenR = (ULONG*)GetProcAddress(m_hMod, "g_uBuffLen"); if (g_szSynchR && g_szBuffR && g_puBuffLenR) { ULONG uBuffLen = *g_puBuffLenR; HANDLE hEvent = ::OpenEvent( EVENT_ALL_ACCESS, FALSE, g_szSynchR ); if ( !hEvent ) { //create synchronized object hEvent = ::CreateEvent( NULL, FALSE/*auto*/, TRUE/*init*/, g_szSynchR ); if ( hEvent ) { WaitForSingleObject( hEvent, INFINITE ); ULONG u = uReadLen>uBuffLen ? uBuffLen : uReadLen; memmove(szBuff, g_szBuffR, u); SetEvent( hEvent ); CloseHandle( hEvent ); hEvent = NULL; } } } } //share dll write if (m_hMod) { char* g_szSynchW = (char*)GetProcAddress(m_hMod, "g_szSynch"); char* g_szBuffW = (char*)GetProcAddress(m_hMod, "g_szBuff"); ULONG* g_puBuffLenW = (ULONG*)GetProcAddress(m_hMod, "g_uBuffLen"); if (g_szSynchW && g_szBuffW && g_puBuffLenW) { ULONG uBuffLen = *g_puBuffLenW; HANDLE hEvent = ::OpenEvent( EVENT_ALL_ACCESS, FALSE, g_szSynchW ); if ( !hEvent ) { //create synchronized object hEvent = ::CreateEvent( NULL, FALSE/*auto*/, TRUE/*init*/, g_szSynchW ); if ( hEvent ) { WaitForSingleObject( hEvent, INFINITE ); ULONG u = uWriteLen>uBuffLen ? uBuffLen : uWriteLen; memmove(g_szBuffW, strSend.GetBuffer(0), u); SetEvent( hEvent ); CloseHandle( hEvent ); hEvent = NULL; } } } } #pragma comment(lib, "../Debug/ShareDll.lib") __declspec(dllimport) char g_szSynch[32]; __declspec(dllimport) char g_szBuff[1024]; __declspec(dllimport) ULONG g_uBuffLen; HANDLE hEvent = ::OpenEvent( EVENT_ALL_ACCESS, FALSE, g_szSynch ); if ( !hEvent ) { //create synchronized object hEvent = ::CreateEvent( NULL, FALSE/*auto*/, TRUE/*init*/, g_szSynch ); if ( hEvent ) { WaitForSingleObject( hEvent, INFINITE ); ULONG u = uWriteLen>g_uBuffLen ? g_uBuffLen : uWriteLen; memset(g_szBuff, 0, g_uBuffLen); memmove(g_szBuff, strSend.GetBuffer(0), u); SetEvent( hEvent ); CloseHandle( hEvent ); hEvent = NULL; } } 1.3 文件/内存映射 m_hMap = ::CreateFileMapping(INVALID_HANDLE_VALUE, //handle null,mem map NULL, PAGE_READWRITE, 0, m_dwMapLen, m_strMapName); 创建映射返回的句柄一旦关闭,相关资源全部释放 //memory map read HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, m_strMapName); if (hMap) { LPVOID lpBuff = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (lpBuff) { char szBuff[1024] = {0}; memmove(szBuff, lpBuff, 1023); if (strlen(szBuff)) { SetDlgItemText(IDC_EDIT2, szBuff); } ::UnmapViewOfFile(hMap); lpBuff = NULL; } CloseHandle(hMap); hMap = NULL; } //memory map write CString strSend; GetDlgItemText(IDC_EDIT1, strSend); ULONG uWriteLen = strSend.GetLength(); if (!uWriteLen) { return; } HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, m_strMapName); if (hMap) { LPVOID lpBuff = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (lpBuff) { memmove(lpBuff, strSend.GetBuffer(0), uWriteLen); ::UnmapViewOfFile(hMap); lpBuff = NULL; } CloseHandle(hMap); hMap = NULL; }
posted on 2016-11-02 17:40 NoneButNow 阅读(198) 评论(0) 编辑 收藏 举报