面对现实,超越自己
逆水行舟,不进则退
posts - 269,comments - 32,trackbacks - 0
C++使用共享内存实现进程间通信
文件映射是一种实现进程间单向或双向通信的机制。它允许两个或多个本地进程间相互通信。为了共享文件或内存,所有的进程必须使用相同的文件映射的名字或是句柄。
为了实现共享文件,第一个进程先调用CreateFile方法。接下来调用CreateFileMapping方法来创建一个文件映射对象。并为文件映射指明一个句柄和名称。由于事件,信号,互斥对象和文件映射等这些内核对象都共享同一个名字空间,所以如果这个名字和其他一个对象的名称重名的话那么将创建失败。
为了实现共享内存,进程应首先调用CreateFileMapping函数然后在hFile参数中传入INVALID_HANDLE_VALUE宏来替代句柄。相应的文件映射对象会从系统的分页文件中获得一段内存。如果hFile参数的值是INVALID_HANDLE_VALUE,那么你在调用CreateFileMapping时必须给共享内存指定一个大小值。
使用共享内存或文件的进程必须使用MapViewOfFile函数或MapViewOfFileEx函数来创建一个文件视图。
示例代码:
服务端:
HANDLE hfilemapping = NULL;
void CCSharedMemoryDlg::OnButton1()
{
    // TODO: Add your control notification handler code here
    hfilemapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 16, "COMBANC_SHARE");
    //创建错误
    if ((hfilemapping == NULL) || (hfilemapping == INVALID_HANDLE_VALUE))
    //    return lx_invalid_sharedmemory;
        MessageBox("error");
    
    //共享内存已经存在
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        MessageBox("共享内存已经存在");
        return;
    }
    BYTE *psize = (BYTE *)MapViewOfFile(hfilemapping, FILE_MAP_WRITE, 0, 0, sizeof(BYTE));
    if(psize == NULL)
    {
        if (hfilemapping != NULL)
        {
            CloseHandle(hfilemapping);
            hfilemapping = NULL;
        }
        return;
    }

    CString sTest = "abc";
    char ch[16] = "COMBANC_TEST";
    memcpy(psize,sTest,sTest.GetLength());
    
    if (psize != NULL)
    {
        UnmapViewOfFile(psize );
        psize = NULL;
    }
}

客户端:
HANDLE hfilemapping = NULL;
void CTestShareMemoryDlg::OnBnClickedButton1()
{
    // TODO: Add your control notification handler code here
     hfilemapping = OpenFileMapping(FILE_MAP_READ, FALSE, "COMBANC_SHARE");
     if ((hfilemapping == NULL) || (hfilemapping == INVALID_HANDLE_VALUE))
         MessageBox("error");
 
    BYTE *psize = (BYTE *)MapViewOfFile(hfilemapping, FILE_MAP_READ, 0, 0, sizeof(BYTE));
    if(psize == NULL)
    {
        if (hfilemapping != NULL)
        {
            CloseHandle(hfilemapping);
            hfilemapping = NULL;
        }
        return;    
    }

    char ch[16];
    memcpy(ch,psize,16);
    MessageBox(ch);

    if (psize  != NULL)
    {
        UnmapViewOfFile(psize );
        psize = NULL;
    }
    if (hfilemapping != NULL)
    {
        CloseHandle(hfilemapping);
        hfilemapping = NULL;
    }
}
posted on 2014-04-11 18:37 王海光 阅读(393) 评论(0)  编辑 收藏 引用 所属分类: C++

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理