进程通信

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编辑  收藏  举报

导航